diff --git a/.gitignore b/.gitignore
index c1e8a1ac9408233861d61b520c7d1a035745f675..37a4eb8b43d978ea05b2c6e3fb934f9b40dddd4d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,15 @@
*.iml
.gradle
/local.properties
-/.idea
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
-gradle*
-/TODO_list.md
-
+.externalNativeBuild
+/entry/.preview
+.cxx
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
deleted file mode 100644
index 96cc43efa6a0885098044e976cd780bb42c68a70..0000000000000000000000000000000000000000
--- a/.idea/compiler.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index e7bedf3377d40335424fd605124d4761390218bb..0000000000000000000000000000000000000000
--- a/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
deleted file mode 100644
index 8ea0936df7d5700b9fd5e1a8b441f162c0442fd3..0000000000000000000000000000000000000000
--- a/.idea/gradle.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 5d19981032aa01b060f5a568641d7a8840cc90dc..0000000000000000000000000000000000000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index a026ddeaf96712fad7370ed7996fe99ab1906908..0000000000000000000000000000000000000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460d8b38ac04e3a3224d7c79ef719b1991a9..0000000000000000000000000000000000000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1ddfbbc029bcab630581847471d7f238ec53..0000000000000000000000000000000000000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..e35f13e36dce7eefde71fdc09901a6ebe4b4b69d
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,6 @@
+## 0.0.1-SNAPSHOT
+ohos 第一个版本,实现了原库的部分api功能:
+1,Webview上做刷新操作无法实现,Webview会覆盖其它组件
+2,ListContenter通过设置toucher监听改变滑动屏幕的刷新样式,Touch监听事件开启再取消后无效。
+3,列表滚动监听,列表滚动刷新太快会导致执行操作处理不及时。
+4,底部拉动 加载更多,滚动数据 和滑动屏幕无法区分,只能通过检查最后一个来做限制
\ No newline at end of file
diff --git a/LICENSE.txt b/LICENSE
similarity index 99%
rename from LICENSE.txt
rename to LICENSE
index d645695673349e3947e8e5ae42332d0ac3164cd7..7a4a3ea2424c09fbe48d455aed1eaa94d9124835 100644
--- a/LICENSE.txt
+++ b/LICENSE
@@ -199,4 +199,4 @@
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.
+ limitations under the License.
\ No newline at end of file
diff --git a/README.OPENSOURCE b/README.OPENSOURCE
new file mode 100644
index 0000000000000000000000000000000000000000..5d69cc60d6ef4ff9324fc52ebe249538ebfe9f61
--- /dev/null
+++ b/README.OPENSOURCE
@@ -0,0 +1,10 @@
+[
+ {
+ "Name": "TwinklingRefreshLayout",
+ "License": "Apache License",
+ "License File": "LICENSE",
+ "Version Number": "master",
+ "Upstream URL": "https://github.com/lcodecorex/TwinklingRefreshLayout",
+ "Description": "TwinklingRefreshLayout延伸了Google的SwipeRefreshLayout的思想,不在列表控件上动刀,而是使用一个ViewGroup来包含列表控件,以保持其较低的耦合性和较高的通用性。"
+ }
+]
\ No newline at end of file
diff --git a/README.md b/README.md
index a198c9dbc84d0b0860c0f41b0221cd2702711788..14cfd005252925bb973409b899369d3360711e1f 100644
--- a/README.md
+++ b/README.md
@@ -1,444 +1,156 @@
-## 【DECREEPTED】
-
# TwinklingRefreshLayout
-[中文文档](./README_CN.md)
-
-TwinklingRefreshLayout extended the thoughts of SwipeRefreshLayout,using a ViewGroup to include a list of Views, to maintain its low coupling and high versatility. Follows are its main features.
-
- - New overscroll animations, running smoothly, much better than iOS.
- - Support RecyclerView, ScrollView, AbsListView, WebView and so on.
- - Support to load more.
- - Default support cross-border rebound.
- - You can open a pure bounds rebound mode.
- - Lots of methods in the class OnRefreshListener.
- - It provides an interface to the callback during the sliding coefficient. Personalized offer good support.
- - NestedScroll,CoordinatorLayout
- **Any View is supported.**
+#### 项目介绍
-
+- 项目名称:TwinklingRefreshLayout
+- 所属系列:openharmony的第三方组件适配移植
+- 功能:TwinklingRefreshLayout延伸了Google的SwipeRefreshLayout的思想,不在列表控件上动刀,而是使用一个ViewGroup来包含列表控件,以保持其较低的耦合性和较高的通用性。
+- 项目移植状态:主功能完成
+- 调用差异:无
+- 开发版本:sdk6,DevEco Studio2.2 Beta1
+- 基线版本:master分支
-## Demo
-[Download Demo](art/app-debug.apk)
+#### 效果演示
-     
+
-You can download these Videos for more details.
+#### 安装教程
-- [Music - ListView - FixedHeader](art/gif_listview.mp4)
-- [Food - RecyclerView - PureScrollMode](art/gif_recyclerview.mp4)
-- [Science - GridView - SinaHeader](art/gif_gridview.mp4)
-- [Photo - RecyclerView - BezierLayout](art/gif_recyclerview2.mp4)
-- [Story - ScrollView - GoogleDotView](art/gif_scrollview.mp4)
-- [Dribbble - WebView - FloatRefresh](art/gif_webview.mp4)
-
-## Usage
-#### 1.Add a gradle dependency.
+1.在项目根目录下的build.gradle文件中,
```
-compile 'com.lcodecorex:tkrefreshlayout:1.0.7'
+allprojects {
+ repositories {
+ maven {
+ url 'https://s01.oss.sonatype.org/content/repositories/snapshots/'
+ }
+ }
+}
```
-
-#### 2.Add TwinklingRefreshLayout in the layout xml.
-```xml
-
-
-
-
-
+2.在entry模块的build.gradle文件中,
```
-
-To get better effect, you'd better add code `android:overScrollMode="never"` to the childView.
-
-#### 3.Coding in the Activity or Fragment.
-##### Change of state need to be manually controlled.
-```java
-refreshLayout.setOnRefreshListener(new RefreshListenerAdapter(){
- @Override
- public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- refreshLayout.finishRefreshing();
- }
- },2000);
- }
-
- @Override
- public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- refreshLayout.finishLoadmore();
- }
- },2000);
- }
- });
- }
-```
-
-Use finishRefreshing() method to end refresh, finishLoadmore() method to end load more. OnRefreshListener there are other methods, you can choose need to override.
-
-And if you want you refresh automatically, call the method startRefresh().
-
-##### setWaveHeight、setHeaderHeight、setBottomHeight、setOverScrollHeight
-- setMaxHeadHeight is used To set the maximum height of the head can be stretched.
-- setHeaderHeight is used to set the standard head height.
-- setMaxBottomHeight.
-- setBottomHeight is used to set the Bottom height.
-- setOverScrollHeight is used to set the max height of overscroll.
-
-And now dp value is supported.
-
-#### setEnableRefresh、setEnableLoadmore
-Flexible settings for whether to disable the pulling-down mode.
-
-##### setHeaderView(IHeaderView headerView)、setBottomView(IBottomView bottomView)
-
-#### setEnableOverScroll
-Whether to allow overscroll mode, opened by default.
-
-##### setOverScrollTopShow、setOverScrollBottomShow、setOverScrollRefreshShow
-Whether to allow the display refresh control on overscrolling, the default is true.
-
-##### setPureScrollModeOn()
-To open the pure overscroll mode so that refreshView would gone permanently.
-
-##### setAutoLoadMore
-if open the loadmore mode after overscrolling bottom automatically.
-
-##### addFixedExHeader
-Allow you to add a view fixed on the top.
-
-##### startRefresh、startLoadMore、finishRefreshing、finishLoadmore
-
-##### setFloatRefresh(boolean)
-Make refresh-animation like SwipeRefreshLayout.
-
-##### setTargetView(View view)
-Set the target view that you can scroll.
-
-##### setDefaultHeader、setDefaultFooter
-static methods aims to set a default header/footer in a/an Application/Activity.
-
-#### 4.Attributes
-- tr_max_head_height - Flexible head height
-- tr_head_height - Head height
-- tr_max_bottom_height
-- tr_bottom_height - Bottom height
-- tr_overscroll_height - OverScroll Height
-- tr_enable_refresh - default is true
-- tr_enable_loadmore - default is true
-- tr_pureScrollMode_on - default is false
-- tr_overscroll_top_show - default is true
-- tr_overscroll_bottom_show - default is true
-- tr_enable_overscroll - default is true.
-- tr_floatRefresh - open the float-refresh mode.
-- tr_autoLoadMore
-- tr_enable_keepIView - default is true.
-- tr_showRefreshingWhenOverScroll - default is true.
-- tr_showLoadingWhenOverScroll - default is true.
-
-## Other
-### 1.setOnRefreshListener
-- onPullingDown(TwinklingRefreshLayout refreshLayout, float fraction)
-- onPullingUp(TwinklingRefreshLayout refreshLayout, float fraction)
-- onPullDownReleasing(TwinklingRefreshLayout refreshLayout, float fraction)
-- onPullUpReleasing(TwinklingRefreshLayout refreshLayout, float fraction)
-- onRefresh(TwinklingRefreshLayout refreshLayout)
-- onLoadMore(TwinklingRefreshLayout refreshLayout)
-
-fraction = currentMoveHeight/headHeight OR (fraction = currentMoveHeight/bottomHeight).
-
-### 3.Header and Footer
-##### BezierLayout(pic 4)
-- setWaveColor
-- setRippleColor
-
-##### GoogleDotView(pic 5)
-##### SinaRefreshView(pic 3)
-- setArrowResource
-- setTextColor
-- setPullDownStr
-- setReleaseRefreshStr
-- setRefreshingStr
-
-##### ProgressLayout(SwipeRefreshLayout pic 6)
-- setProgressBackgroundColorSchemeResource(@ColorRes int colorRes)
-- setProgressBackgroundColorSchemeColor(@ColorInt int color)
-- setColorSchemeResources(@ColorRes int... colorResIds)
-
-####Footer
-##### BallPulseView(pic 2)
-- setNormalColor(@ColorInt int color)
-- setAnimatingColor(@ColorInt int color)
-
-##### LoadingView(pic 3)
-Here is more animations.[AVLoadingIndicatorView](https://github.com/81813780/AVLoadingIndicatorView)。
-
-### 3.Personalize the Header and Footer.
-The Header needs to implement IHeaderView interface and Footer in in the same way(IBottomView).
-```java
-public interface IHeaderView {
- View getView();
-
- void onPullingDown(float fraction,float maxHeadHeight,float headHeight);
-
- void onPullReleasing(float fraction,float maxHeadHeight,float headHeight);
-
- void startAnim(float maxHeadHeight,float headHeight);
-
- void reset();
+dependencies {
+ implementation('com.gitee.chinasoft_ohos:TwinklingRefreshLayout_library:0.0.1-SNAPSHOT')
+ ......
}
```
+在sdk6,DevEco Studio2.2 Beta1 下项目可直接运行 如无法运行,删除项目.gradle,.idea,build,gradle,build.gradle文件, 并依据自己的版本创建新项目,将新项目的对应文件复制到根目录下
-getView() method is not allow to return null.
+#### 使用说明
-#### Let's implement a simple refresh dynamic efficiency.
-1.Define SinaRefreshHeader extended from FrameLayout and implement IHeaderView interface.
+Demo中调用library组件库,操作展示组件功能。
-2.Return this in the method getView().
+1、布局文件中引用界面效果:
+```xml
+
+```
+列表展示功能主要再 XRecyclerView类中。
+其中 density属性 是列表的头部和尾部样式类型。
-3.Inflate and find Views in the layout xml.
+自定义类 ArrowRefreshHeader 是头部刷新效果:
```java
-void init() {
- if (rootView == null) {
- rootView = View.inflate(getContext(), R.layout.view_sinaheader, null);
- refreshArrow = (ImageView) rootView.findViewById(R.id.iv_arrow);
- refreshTextView = (TextView) rootView.findViewById(R.id.tv);
- loadingView = (ImageView) rootView.findViewById(R.id.iv_loading);
- addView(rootView);
+public void headView(Context context){
+ LayoutScatter scatter = LayoutScatter.getInstance(context);
+ mContainer = (DirectionalLayout) scatter.parse(ResourceTable.Layout_listview_header, null, false);
+
+ listview_header_text = (DirectionalLayout) mContainer.findComponentById(ResourceTable.Id_listview_header_text); // 功能3 箭头和提示刷新
+ cricle_refresh = (DirectionalLayout) mContainer.findComponentById(ResourceTable.Id_cricle_refresh); // 功能1 圆圈刷新
+ mHeaderRefreshTimeContainer = (DirectionalLayout) mContainer.findComponentById(ResourceTable.Id_header_refresh_time_container);
+
+ DirectionalLayout.LayoutConfig lp = new DirectionalLayout.LayoutConfig(DirectionalLayout.LayoutConfig.MATCH_PARENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT);
+ lp.setMargins(0, 0, 0, 0);
+ this.setPadding(0, 0, 0, 0);
+ this.setLayoutConfig(lp);
+
+ addComponent(mContainer, new DirectionalLayout.LayoutConfig(DirectionalLayout.LayoutConfig.MATCH_PARENT, 0));
+ setAlignment(TextAlignment.BOTTOM);
+
+ frameAnimationElement = new FrameAnimationElement(context, ResourceTable.Graphic_anim_loading_view);
+ componentContainer = (DirectionalLayout) findComponentById(ResourceTable.Id_frame_container);
+ mArrowImageView = (Image) mContainer.findComponentById(ResourceTable.Id_listview_header_arrow);
+ mStatusTextView = (Text) mContainer.findComponentById(ResourceTable.Id_refresh_status_textview);
+ mHeaderTimeView = (Text) mContainer.findComponentById(ResourceTable.Id_last_refresh_time);
+
+ head_top = (DirectionalLayout) mContainer.findComponentById(ResourceTable.Id_head_top);
+ if (XRecyclerView.stateInfo == 3) { // 功能3的刷新
+ listview_header_text.setVisibility(VISIBLE);
+ mArrowImageView.setVisibility(VISIBLE);
+ cricle_refresh.setVisibility(HIDE);
+ } else if(XRecyclerView.stateInfo == 1) {
+ cricle_refresh.setVisibility(VISIBLE);
+ listview_header_text.setVisibility(HIDE);
+ } else if(XRecyclerView.stateInfo == 5) {
+ cricle_refresh.setVisibility(HIDE);
+ listview_header_text.setVisibility(HIDE);
+ head_top.setVisibility(VISIBLE);
}
- }
-```
-
-4.Override some methods.
-```java
-@Override
- public void onPullingDown(float fraction, float maxHeadHeight, float headHeight) {
- if (fraction < 1f) refreshTextView.setText(pullDownStr);
- if (fraction > 1f) refreshTextView.setText(releaseRefreshStr);
- refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180);
-
-
- }
-
- @Override
- public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) {
- if (fraction < 1f) {
- refreshTextView.setText(pullDownStr);
- refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180);
- if (refreshArrow.getVisibility() == GONE) {
- refreshArrow.setVisibility(VISIBLE);
- loadingView.setVisibility(GONE);
- }
+ //init the progress view
+ mProgressBar = (SimpleViewSwitcher) mContainer.findComponentById(ResourceTable.Id_listview_header_progressbar);
+ progressView = new AVLoadingIndicatorView(context);
+ progressView.setIndicatorColor(0xffB5B5B5);
+ progressView.setIndicatorId(ProgressStyle.BallSpinFadeLoader);
+ if (mProgressBar != null) {
+ mProgressBar.setView(progressView);
+ progressView.applyAnimation();
}
+ estimateSize(ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
+ mMeasuredHeight = getEstimatedHeight();
+ loadingView = (LoadingView)
+ mContainer.findComponentById(ResourceTable.Id_progress_bar_loading);
+ loadingView.setBindStateChangedListener(loadingView);
+ loadingView.setPaintcolor(0xff000000);
+ loadingView.setSize(45);
+ loadingView.stopAnimation();
}
- @Override
- public void startAnim(float maxHeadHeight, float headHeight) {
- refreshTextView.setText(refreshingStr);
- refreshArrow.setVisibility(GONE);
- loadingView.setVisibility(VISIBLE);
- }
-
- @Override
- public void onFinish(OnAnimEndListener listener) {
- listener.onAnimEnd();
- }
-```
-
-5.layout xml.
-```xml
-
-
-
-
-
-
-
-
-```
-
-Pay attention to the using of the parameter `fraction`. Such as the code above`refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180)`,`fraction * headHeight` is the translationY of the Head and 180 is the angle the arrow would rotate,so that we can make the arrow rotate 180 degrees when the translationY is come to the maxHeadHeight.
-
-
-onPullingDown/onPullingUp
-onPullReleasing
-startAnim - be called automatically after the method onRefresh/onLoadMore is called.
-
-Congratulations! Simple to use and simple to Personalise.(To see a more simple example. **TextHeaderView(pic 4)**)。
-
-### NestedScroll
-#### TwinklingRefreshLayout Nested CoordinatorLayout
----layout
-```xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
```
---- code1
-```
-refreshLayout.setTargetView(rv);
-```
-Find the RecyclerView/ListView.
+自定义类 LoadingMoreFooter 是尾部加载更多效果:
---- code2
```java
-AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar_layout);
-appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
- @Override
- public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
- if (verticalOffset >= 0) {
- refreshLayout.setEnableRefresh(true);
- refreshLayout.setEnableOverScroll(false);
- } else {
- refreshLayout.setEnableRefresh(false);
- refreshLayout.setEnableOverScroll(false);
+ private void initView(Context context, AttrSet attrSet, String styleName){
+ setAlignment(CENTER);
+ setOrientation(HORIZONTAL);
+ setComponentSize(LayoutConfig.MATCH_PARENT, DeviceUtils.dp2px(getContext(),5));
+ progressCon = new SimpleViewSwitcher(context);
+ progressCon.setWidth(DeviceUtils.dp2px(getContext(),40));
+ progressCon.setHeight(DeviceUtils.dp2px(getContext(),40));
+ addComponent(progressCon);
+
+ if (XRecyclerView.stateInfo == 3) {
+ addHeadFoot();
+ } else if(XRecyclerView.stateInfo == 1 || XRecyclerView.stateInfo == 5){
+ addText();
}
+
}
-});
```
+2、自定义刷新和加载跟多效果属性
+```java
+ mRecyclerView.setPullRefreshEnabled(false); // 设置刷新的开启状态,默认开启
+ mRecyclerView.setLoadingMoreEnabled(false); // 设置加载更多的状态,默认是开启
+ mRecyclerView.setLongClickable(false); // 设置长按
+ mRecyclerView.setReboundEffect(true); //设置上下滚动效果
+ photoAdapter.setNumColumns(2); //设置列表的列数
-####CoordinatorLayout nested TwinklingRefreshLayout
---- layout
-```xml
-
-
-
-
-
-
-
-
-
-
```
-Pay attention to `layout_behavior="@string/appbar_scrolling_view_behavior"` for TwinklingRefreshLayout.
-
-> ps:Contact me: lcodecore@163.com
-> QQ group: 202640706
-
-If you like this library, you can donate me. Buy me a coffee!
-
- 
-
-## Update Logs
-#### v1.07
-- NestedScroll,CoordinateLayout
-- Any View
-- Keep state when refreshing/loading.
-
-#### v1.06
-- Repair memory leaks of customized Views.
-- remove the dependence of AVLoadingIndicatorView.
-- Fix bugs of OverScroll when TargetView scrolls at the top/bottom.
-- Repair bugs of touching,scroll-event listeners.
-- Optimization of interface flicker problems after load-more.
-
-#### v1.05 Emergency Fix
-- Fix the bug of setAutoLoadMore().
-- Fix the bug that FixedHeader covered the first item of listview.
-- Add onRefreshCanceled()/onLoadmoreCanceled() for RefreshListenerAdapter.
-#### v1.04
-- Refactor the code.
-- Make animations smoothly.
-- Add support to Fixed Header.
-- Add support to float refresh mode.
-- IHeadView.onFinish(animEndListener) -> Available to run animations before finishRefresh.
+#### 测试信息
-#### v1.03
-- more attributes.
-- Fix the NullPointerException bug in Fragment.
-- Fix the Sliding conflict.
+CodeCheck代码测试无异常
+CloudTest代码测试无异常
-License
--------
+病毒安全检测通过
- Copyright 2016 lcodecorex
+当前版本demo功能与原组件基本无差异
- 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
+当前版本demo部分功能暂不支持模拟器运行
- 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.
+- 0.0.1-SNAPSHOT
\ No newline at end of file
diff --git a/README_CN.md b/README_CN.md
deleted file mode 100644
index 6ba9e6eb15ecc37f347399c31a63e189cac4815d..0000000000000000000000000000000000000000
--- a/README_CN.md
+++ /dev/null
@@ -1,491 +0,0 @@
-# TwinklingRefreshLayout
-TwinklingRefreshLayout延伸了Google的SwipeRefreshLayout的思想,不在列表控件上动刀,而是使用一个ViewGroup来包含列表控件,以保持其较低的耦合性和较高的通用性。其主要特性有:
-
-1. 支持RecyclerView、ScrollView、AbsListView系列(ListView、GridView)、WebView以及其它可以获取到scrollY的控件
-2. 支持加载更多
-3. 默认支持 **越界回弹**,随手势速度有不同的效果
-4. 可开启没有刷新控件的纯净越界回弹模式
-5. setOnRefreshListener中拥有大量可以回调的方法
-6. 将Header和Footer抽象成了接口,并回调了滑动过程中的系数,方便实现个性化的Header和Footer
-7. 支持NestedScroll,嵌套CoordinatorLayout
-
-**目前已经支持了所有的View,比如是一个FrameLayout,LinearLayout,AnyView。**
-
-
-
-## Demo
-[下载Demo](art/app-debug.apk)
-
-     
-
-You can download these Videos for more details.
-
-- [Music - ListView - FixedHeader](art/gif_listview.mp4)
-- [Food - RecyclerView - PureScrollMode](art/gif_recyclerview.mp4)
-- [Science - GridView - SinaHeader](art/gif_gridview.mp4)
-- [Photo - RecyclerView - BezierLayout](art/gif_recyclerview2.mp4)
-- [Story - ScrollView - GoogleDotView](art/gif_scrollview.mp4)
-- [Dribbble - WebView - FloatRefresh](art/gif_webview.mp4)
-
-## 使用方法
-#### 1.添加gradle依赖
-将libray模块复制到项目中,或者直接在build.gradle中依赖:
-```
-compile 'com.lcodecorex:tkrefreshlayout:1.0.7'
-```
-
-#### 2.在xml中添加TwinklingRefreshLayout
-```xml
-
-
-
-
-
-```
-
-Android系统为了跟iOS不一样,当界面OverScroll的时候会显示一个阴影。为了达到更好的显示效果,最好禁用系统的overScroll,如上给RecyclerView添加`android:overScrollMode="never"`。
-
-#### 3.在Activity或者Fragment中配置
-##### TwinklingRefreshLayout不会自动结束刷新或者加载更多,需要手动控制
-```java
-refreshLayout.setOnRefreshListener(new RefreshListenerAdapter(){
- @Override
- public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- refreshLayout.finishRefreshing();
- }
- },2000);
- }
-
- @Override
- public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- refreshLayout.finishLoadmore();
- }
- },2000);
- }
- });
- }
-```
-使用finishRefreshing()方法结束刷新,finishLoadmore()方法结束加载更多。此处OnRefreshListener还有其它方法,可以选择需要的来重写。
-
-如果你想进入到界面的时候主动调用下刷新,可以调用startRefresh()/startLoadmore()方法。
-
-##### setWaveHeight、setHeaderHeight、setBottomHeight、setOverScrollHeight
-- setMaxHeadHeight 设置头部可拉伸的最大高度。
-- setHeaderHeight 头部固定高度(在此高度上显示刷新状态)
-- setMaxBottomHeight
-- setBottomHeight 底部高度
-- setOverScrollHeight 设置最大的越界高度
-
-#### setEnableRefresh、setEnableLoadmore
-灵活的设置是否禁用上下拉。
-
-##### setHeaderView(IHeaderView headerView)、setBottomView(IBottomView bottomView)
-设置头部/底部个性化刷新效果,头部需要实现IHeaderView,底部需要实现IBottomView。
-
-#### setEnableOverScroll
-是否允许越界回弹。
-
-##### setOverScrollTopShow、setOverScrollBottomShow、setOverScrollRefreshShow
-是否允许在越界的时候显示刷新控件,默认是允许的,也就是Fling越界的时候Header或Footer照常显示,反之就是不显示;可能有特殊的情况,刷新控件会影响显示体验才设立了这个状态。
-
-##### setPureScrollModeOn()
-开启纯净的越界回弹模式,也就是所有刷新相关的View都不显示,只显示越界回弹效果
-
-##### setAutoLoadMore
-是否在底部越界的时候自动切换到加载更多模式
-
-##### addFixedExHeader
-添加一个固定在顶部的Header(效果还需要优化)
-
-##### startRefresh、startLoadMore、finishRefreshing、finishLoadmore
-
-##### setFloatRefresh(boolean)
-支持切换到像SwipeRefreshLayout一样的悬浮刷新模式了。
-
-##### setTargetView(View view)
-设置滚动事件的作用对象。
-
-##### setDefaultHeader、setDefaultFooter
-现在已经提供了设置默认的Header、Footer的static方法,可在Application或者一个Activity中这样设置:
-```java
-TwinklingRefreshLayout.setDefaultHeader(SinaRefreshView.class.getName());
-TwinklingRefreshLayout.setDefaultFooter(BallPulseView.class.getName());
-```
-
-
-#### 4.扩展属性
-- tr_max_head_height 头部拉伸允许的最大高度
-- tr_head_height 头部高度
-- tr_max_bottom_height
-- tr_bottom_height 底部高度
-- tr_overscroll_height 允许越界的最大高度
-- tr_enable_refresh 是否允许刷新,默认为true
-- tr_enable_loadmore 是否允许加载更多,默认为true
-- tr_pureScrollMode_on 是否开启纯净的越界回弹模式
-- tr_overscroll_top_show - 否允许顶部越界时显示顶部View
-- tr_overscroll_bottom_show 是否允许底部越界时显示底部View
-- tr_enable_overscroll 是否允许越界回弹
-- tr_floatRefresh 开启悬浮刷新模式
-- tr_autoLoadMore 越界时自动加载更多
-- tr_enable_keepIView 是否在开始刷新之后保持状态,默认为true;若需要保持原来的操作逻辑,这里设置为false即可
-- tr_showRefreshingWhenOverScroll 越界时直接显示正在刷新中的头部
-- tr_showLoadingWhenOverScroll 越界时直接显示正在加载更多中的底部
-
-## 其它说明
-### 1.默认支持越界回弹,并可以随手势越界不同的高度
-这一点很多类似SwipeRefreshLayout的刷新控件都没有做到(包括SwipeRefreshLayout),因为没有拦截下来的时间会传递给列表控件,而列表控件的滚动状态很难获取。解决方案就是给列表控件设置了OnTouchListener并把事件交给GestureDetector处理,然后在列表控件的OnScrollListener中监听View是否滚动到了顶部(没有OnScrollListener的则采用延时监听策略)。
-
-### 2.setOnRefreshListener大量可以回调的方法
-- onPullingDown(TwinklingRefreshLayout refreshLayout, float fraction) 正在下拉的过程
-- onPullingUp(TwinklingRefreshLayout refreshLayout, float fraction) 正在上拉的过程
-- onPullDownReleasing(TwinklingRefreshLayout refreshLayout, float fraction) 下拉释放过程
-- onPullUpReleasing(TwinklingRefreshLayout refreshLayout, float fraction) 上拉释放过程
-- onRefresh(TwinklingRefreshLayout refreshLayout) 正在刷新
-- onLoadMore(TwinklingRefreshLayout refreshLayout) 正在加载更多
-
-其中fraction表示当前下拉的距离与Header高度的比值(或者当前上拉距离与Footer高度的比值)。
-
-### 3.Header和Footer
-##### BezierLayout(pic 4)
-- setWaveColor
-- setRippleColor
-
-##### GoogleDotView(pic 5)
-##### SinaRefreshView(pic 3)
-- setArrowResource
-- setTextColor
-- setPullDownStr
-- setReleaseRefreshStr
-- setRefreshingStr
-
-##### ProgressLayout(SwipeRefreshLayout pic 6)
-- setProgressBackgroundColorSchemeResource(@ColorRes int colorRes)
-- setProgressBackgroundColorSchemeColor(@ColorInt int color)
-- setColorSchemeResources(@ColorRes int... colorResIds)
-
-####Footer
-##### BallPulseView(pic 2)
-- setNormalColor(@ColorInt int color)
-- setAnimatingColor(@ColorInt int color)
-
-##### LoadingView(pic 3)
-更多动效可以参考[AVLoadingIndicatorView](https://github.com/81813780/AVLoadingIndicatorView)库。
-
-
-### 3.实现个性化的Header和Footer
-相关接口分别为IHeaderView和IBottomView,代码如下:
-```java
-public interface IHeaderView {
- View getView();
-
- void onPullingDown(float fraction,float maxHeadHeight,float headHeight);
-
- void onPullReleasing(float fraction,float maxHeadHeight,float headHeight);
-
- void startAnim(float maxHeadHeight,float headHeight);
-
- void reset();
-}
-```
-
-其中getView()方法用于在TwinklingRefreshLayout中获取到实际的Header,因此不能返回null。
-
-**实现像新浪微博那样的刷新效果**(有部分修改,具体请看源码),实现代码如下:
-
-1.首先定义SinaRefreshHeader继承自FrameLayout并实现IHeaderView方法
-
-2.getView()方法中返回this
-
-3.在onAttachedToWindow()或者构造函数方法中获取一下需要用到的布局
-
-4. 在onFinish()方法中调用listener.onAnimEnd()。此方法的目的是为了在finish之前可以执行一段动画。
-
-```java
-private void init() {
- View rootView = View.inflate(getContext(), R.layout.view_sinaheader, null);
- refreshArrow = (ImageView) rootView.findViewById(R.id.iv_arrow);
- refreshTextView = (TextView) rootView.findViewById(R.id.tv);
- loadingView = (ImageView) rootView.findViewById(R.id.iv_loading);
- addView(rootView);
- }
-```
-
-4.实现其它方法
-```java
-@Override
- public void onPullingDown(float fraction, float maxHeadHeight, float headHeight) {
- if (fraction < 1f) refreshTextView.setText(pullDownStr);
- if (fraction > 1f) refreshTextView.setText(releaseRefreshStr);
- refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180);
-
-
- }
-
- @Override
- public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) {
- if (fraction < 1f) {
- refreshTextView.setText(pullDownStr);
- refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180);
- if (refreshArrow.getVisibility() == GONE) {
- refreshArrow.setVisibility(VISIBLE);
- loadingView.setVisibility(GONE);
- }
- }
- }
-
- @Override
- public void startAnim(float maxHeadHeight, float headHeight) {
- refreshTextView.setText(refreshingStr);
- refreshArrow.setVisibility(GONE);
- loadingView.setVisibility(VISIBLE);
- }
-
- @Override
- public void onFinish(OnAnimEndListener listener) {
- listener.onAnimEnd();
- }
-```
-
-5.布局文件
-```xml
-
-
-
-
-
-
-
-
-```
-
-注意fraction的使用,比如上面的代码`refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180)`,`fraction * headHeight`表示当前头部滑动的距离,然后算出它和最大高度的比例,然后乘以180,可以使得在滑动到最大距离时Arrow恰好能旋转180度。
-
-
-onPullingDown/onPullingUp表示正在下拉/正在上拉的过程。
-onPullReleasing表示向上拉/下拉释放时回调的状态。
-startAnim则是在onRefresh/onLoadMore之后才会回调的过程(此处是显示了加载中的小菊花)
-
-如上所示,轻而易举就可以实现一个个性化的Header或者Footer。(更简单的实现请参考Demo中的 **TextHeaderView(图四)**)。
-
-### NestedScroll
-#### TwinklingRefreshLayout嵌套CoordinatorLayout
----layout
-```xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
---- 代码1
-```
-refreshLayout.setTargetView(rv);
-```
-让refreshLayout能够找到RecyclerView/ListView
-
---- 代码2
-```java
-AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar_layout);
-appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
- @Override
- public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
- if (verticalOffset >= 0) {
- refreshLayout.setEnableRefresh(true);
- refreshLayout.setEnableOverScroll(false);
- } else {
- refreshLayout.setEnableRefresh(false);
- refreshLayout.setEnableOverScroll(false);
- }
- }
-});
-```
-设置AppBarLayout的移动监听器,需要下拉显示AppBarLayout时需设置setEnableRefresh(false),setEnableOverScroll(false);AppBarLayout隐藏后还原为原来设置的值即可。
-
-####CoordinatorLayout嵌套TwinklingRefreshLayout
---- layout
-```xml
-
-
-
-
-
-
-
-
-
-
-```
-注意给TwinklingRefreshLayout设置一个layout_behavior="@string/appbar_scrolling_view_behavior"
-
-## TODO
-- 制作一个star相关的动效
-- 带视差效果的Header
-
-> ps:如有任何问题或者是建议,可以邮箱联系我!(lcodecore@163.com)
-> 如有问题或新的需求,请加QQ群202640706讨论,开源库会根据需求持续更新。
-
-开源库消耗了我大量的精力和时间,如果你喜欢这个库或者对自己有所帮助,还请多多支持我。Buy me a coffee!
-
- 
-
-## 更新日志
-#### v1.07
-- 你们要的设置默认刷新头/脚的方法来啦
-- Demo中集成StrictMode、BlockCanary检测ANR
-- 支持NestedScroll
-- 修复item点击失效/点击闪烁的问题
-- Nested滑动显示刷新头/尾支持
-- 支持刷新/加载更多状态保持
-- 空白View亦可刷新/加载
-
-#### v1.06
-- 修复触摸监听失效问题
-- 修复wrap_content时刷新控件显示在屏幕中央问题
-- 去除AVLoadingIndicatorView等依赖,改为BallPulseView
-- 优化加载更多完成时出现的闪烁问题
-- 修复ValueAnimator以及Demo中WebView带来的内存泄漏问题
-- 理论上解决了触摸、点击以及滚动监听失效等问题
-- 新增setTargetView()方法,可设置滚动事件的作用对象
-- 添加了CoordinateLayout demo(暂未在RefreshLayout中添加相关逻辑)
-- 修复三星、酷派手机出现的兼容问题
-- 修复禁用refresh、loadmore后overscroll不可用的问题
-- 修复在顶部、底部fling时页面闪烁问题
-- 修复IBottomView中的参数错误,新增max_head_height,max_bottom_height属性,setWaveHeight方法为setMaxHeadHeight
-
-#### v1.05紧急修复版
-- 修复底部自动加载更多问题
-- 修复FixedHeader遮挡item问题
-- RefreshListenerAdapter添加接口onRefreshCanceled()/onLoadmoreCanceled() 回调刷新被取消的状态
-- 修复刷新状态重复回调问题
-- 添加Apache License 2.0开源协议
-
-#### v1.04
-##### 新增功能
-- **第二次重构完成**,将核心逻辑拆分为RefreshProcessor、AnimProcessor、OverScrollProcessor、CoProcessor
-- **优化越界策越,手势决定越界高度**
-- **优化界面流畅度**
-- 添加类似SwipeRefreshLayout的**悬浮刷新**功能(ProgressLayout)
-- 滑到底部**自动加载更多**or回弹可选,默认为回弹
-- 允许在结束刷新之前执行一个动效:IHeadView.onFinish(animEndListener)
-- 新增支持Header(Beta)
-- 优化BezierLayout、SinaRefreshLayout等的显示并增加调节属性
-- 新增支持设置是否允许OverScroll
-
-##### fixed bugs
-- 修复刷新或加载更多时,列表item没有铺满列表控件,滑动无效的问题
-- 添加主动刷新/加载更多的方法:startRefresh(),startLoadMore()
-- 修复顶部和底部越界高度不一致的问题
-- 修复WebView在底部fling时不能越界的问题
-- 动画执行时间与高度相关,动效更加柔和
-
-
-#### v1.03
-- 扩展了更多的属性
-- 修复Fragment回收导致的空指针异常问题
-- 加入x方向判断,减小了滑动冲突
-- 优化加载更多列表显示问题
-- 可以灵活的设置是否禁用上下拉
-- 修复GridView滑动过程中出现的白条问题
-- Demo中添加轮播条展示
-
-#### v1.02
-- 修复加载更多列表控件的显示问题
-
-#### v1.01
-- 支持了RecyclerView、ScrollView、AbsListView、WebView
-- 支持越界回弹
-- 支持个性化Header、Footer
-
-
-License
--------
-
- Copyright 2016 lcodecorex
-
- 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/TODO_list.md b/TODO_list.md
deleted file mode 100644
index 60426e0f0662c0c5f03877cbf77c311adb46126b..0000000000000000000000000000000000000000
--- a/TODO_list.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# v1.07开发计划
-- 华为7.0 P9奔溃问题
-- setFloatRefresh(true)下拉刷新不可见问题 --View添加顺序的问题 **done**
-- 确认item点击失效问题是否解决
-- header添加时机的空指针和不显示问题 --去掉post **done**
-- 提供设置默认header、footer的方法 **done**
-- 频繁设置禁止下拉和加载失效问题?(增加RefreshMode类)
-- fixedHeader ontouch事件无响应,需手动设置clickable=true
-- setOverScrollTopShow(false)/setOverScrollBottomShow(false)/setOverScrollRefreshShow(false) 设置无效 **done**
-- 兼容nestedscroll
-- 状态保持问题
-- onFinishRefresh不回调问题
-- 刷新时禁止加载更多,去加载更多底部空白没回去
-- 空白View下拉无效
-- 不停下拉导致head悬浮
-- 测试autoLoadMore
-
-
-# v1.06开发计划
-## 存在的问题
-1. 三星、酷派手机的兼容问题
-2. 依赖太旧的问题->选择去除依赖还是更新依赖 **done** 已去除依赖
-3. 自动刷新动画生硬 todo 问题待验证
-4. 加载更多闪烁问题 **done** 做了优化
-5. layout_behavior支持问题 添加了Demo但未完成任何逻辑处理
-6. 是否要支持ViewPager回弹问题 TODO
-7. 是否要支持所有的View TODO 不能滑动NormalView是因为没有焦点的原因(需手动设置),暂时不考虑支持
-8. 测试事件监听冲突问题 理论上修改后已经不存在这个问题 **done**
-9. 内存泄漏问题 -> 解决ValueAnimator潜在的内存泄漏问题;WebView内存泄漏问题;**done**
-10. 仿QQ视差效果
-11. 测试加载更多后不添加数据 **done**
-12. 考虑是否要给Loadmore添加完成延时
-13. FixedHeader问题
-14. 多点触摸处理
-15. 控制底部下拉后或者顶部上拉后再次进入动画可以保持!
-16. Refresh和OverScroll的开关耦合问题,即禁用loadmore后OverScroll不可用问题 **done**
-17. 测试自动加载更多功能是否正常 **done**正常
-
-## 新发现的问题
-1. beizierlayout主动调用刷新时会一片白 todo
-2. BallPulseView引入了内存泄漏 **done**
-3. 新的方案,怎么让scroll更平滑;计算Footer降低与TargetView显示距离是否一致:结论,一致,问题在每次滚动的距离上 **done**
-4. requestLayout时提示 **improperly called by android.support.v7.widget.AppCompatTextView**
-5. WebView上拉不起作用 **done**
-6. 修改IBottomView中的参数错误,增加max_head_height,max_bottom_height属性;修改setWaveHeight方法为setMaxHeadHeight,增加setMaxBottomHeight方法 **done**
-7. 在最顶部或最底部时fling会多次反弹 **done**(解决办法,在最顶端fling时不响应动作)
diff --git a/app/build.gradle b/app/build.gradle
deleted file mode 100644
index 9b0ae19ee591a257828fedaab99f9771157c198e..0000000000000000000000000000000000000000
--- a/app/build.gradle
+++ /dev/null
@@ -1,35 +0,0 @@
-apply plugin: 'com.android.application'
-
-android {
- compileSdkVersion 25
- buildToolsVersion '25.0.1'
- defaultConfig {
- applicationId 'com.lcodecore.twinklingrefreshlayout'
- minSdkVersion 14
- targetSdkVersion 22
- versionCode 1
- versionName "1.0"
- }
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
- productFlavors {
- }
- lintOptions {
- abortOnError false
- }
-}
-
-dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
- compile 'com.android.support:design:25.2.0'
- compile project(':library')
- compile 'com.android.support:appcompat-v7:25.2.0'
- compile 'com.android.support:cardview-v7:25.2.0'
- compile 'com.jakewharton:butterknife:7.0.1'
- compile 'com.squareup.leakcanary:leakcanary-android:1.5'
- compile 'com.github.moduth:blockcanary-android:1.2.1'
-}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
deleted file mode 100644
index aaf9d0a0a103563d2430a854fa6719ef034f5046..0000000000000000000000000000000000000000
--- a/app/proguard-rules.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /Users/lcodecore/Documents/android_sdk_macosx/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
deleted file mode 100644
index 4f46c6d5d43e9d973a4ec8c89fbf42d9086de0d7..0000000000000000000000000000000000000000
--- a/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/BaseActivity.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/BaseActivity.java
deleted file mode 100644
index 1334114ee63ba2d15ed01fbb21a67eafe9c8316e..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/BaseActivity.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
-import android.view.View;
-
-/**
- * Created by lcodecore on 16/3/2.
- */
-public abstract class BaseActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(setInflateId());
- init();
- initAcition();
- }
-
- //设置布局id
- public abstract int setInflateId();
-
- //视图,组件,数据的初始化
- public abstract void init();
-
- //事件监听
- public void initAcition(){}
-
- //Activity设置带返回按钮的Toolbar
- public void setupBackToolbar(String title){
- setupBackToolbar(R.id.toolbar,title);
- }
-
- public void setupBackToolbar(int toolbarId,String title){
- Toolbar mToolbar = (Toolbar) findViewById(toolbarId);
- setSupportActionBar(mToolbar);
- getSupportActionBar().setHomeButtonEnabled(true); //显示小箭头
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- onBackPressed();
- }
- });
- setTitle(title);
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/CoordinateActivity.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/CoordinateActivity.java
deleted file mode 100644
index a8695951bdb48bb6b946b52788ff0bb627803810..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/CoordinateActivity.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.design.widget.AppBarLayout;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.StaggeredGridLayoutManager;
-import android.view.WindowManager;
-
-import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-import com.lcodecore.tkrefreshlayout.header.progresslayout.ProgressLayout;
-import com.lcodecore.twinklingrefreshlayout.adapter.PhotoAdapter;
-import com.lcodecore.twinklingrefreshlayout.beans.Photo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Created by lcodecore on 2017/3/8.
- */
-
-public class CoordinateActivity extends AppCompatActivity {
- private PhotoAdapter photoAdapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_coordinate);
-
- setupRecyclerView((RecyclerView) findViewById(R.id.recyclerview));
-
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
- }
-
- private void setupRecyclerView(RecyclerView rv) {
- rv.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
- photoAdapter = new PhotoAdapter();
- rv.setAdapter(photoAdapter);
-
- final TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
- ProgressLayout header = new ProgressLayout(this);
- refreshLayout.setHeaderView(header);
- refreshLayout.setFloatRefresh(true);
- refreshLayout.setEnableOverScroll(false);
- refreshLayout.setHeaderHeight(140);
- refreshLayout.setMaxHeadHeight(240);
- refreshLayout.setTargetView(rv);
-
- refreshCard();
-
- refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
- @Override
- public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- refreshCard();
- refreshLayout.finishRefreshing();
- }
- }, 2000);
- }
-
- @Override
- public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- loadMoreCard();
- refreshLayout.finishLoadmore();
- }
- }, 2000);
- }
- });
-
- AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar_layout);
- appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
- @Override
- public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
- if (verticalOffset >= 0) {
- refreshLayout.setEnableRefresh(true);
- refreshLayout.setEnableOverScroll(false);
- } else {
- refreshLayout.setEnableRefresh(false);
- refreshLayout.setEnableOverScroll(false);
- }
- }
- });
- }
-
- void refreshCard() {
- List photos = new ArrayList<>();
- photos.add(new Photo("chest nut", R.drawable.photo1));
- photos.add(new Photo("fish", R.drawable.photo2));
- photos.add(new Photo("cat", R.drawable.photo10));
- photos.add(new Photo("guitar", R.drawable.photo3));
- photos.add(new Photo("common-hazel", R.drawable.photo4));
- photos.add(new Photo("cherry", R.drawable.photo5));
- photos.add(new Photo("flower details", R.drawable.photo6));
- photos.add(new Photo("tree", R.drawable.photo7));
- photos.add(new Photo("blue berries", R.drawable.photo8));
- photos.add(new Photo("snow man", R.drawable.photo9));
- photoAdapter.setDataList(photos);
- }
-
- void loadMoreCard() {
- List photos = new ArrayList<>();
- photos.add(new Photo("chest nut", R.drawable.photo1));
- photos.add(new Photo("fish", R.drawable.photo2));
- photos.add(new Photo("cat", R.drawable.photo10));
- photos.add(new Photo("guitar", R.drawable.photo3));
- photos.add(new Photo("common-hazel", R.drawable.photo4));
- photos.add(new Photo("cherry", R.drawable.photo5));
- photos.add(new Photo("flower details", R.drawable.photo6));
- photos.add(new Photo("tree", R.drawable.photo7));
- photos.add(new Photo("blue berries", R.drawable.photo8));
- photos.add(new Photo("snow man", R.drawable.photo9));
- photoAdapter.addItems(photos);
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/FoodActivity.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/FoodActivity.java
deleted file mode 100644
index dc1725ecdb0af25cf5339821d9ccb570d47eb3ac..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/FoodActivity.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.view.View;
-import android.view.WindowManager;
-
-import com.lcodecore.tkrefreshlayout.header.bezierlayout.BezierLayout;
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-import com.lcodecore.twinklingrefreshlayout.adapter.FoodAdapter;
-import com.lcodecore.twinklingrefreshlayout.beans.Food;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class FoodActivity extends AppCompatActivity {
-
- private FoodAdapter foodAdapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_food);
- setupRecyclerView((RecyclerView) findViewById(R.id.recyclerview));
-
- findViewById(R.id.bt_back).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- finish();
- }
- });
-
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
- }
-
- private void setupRecyclerView(RecyclerView rv) {
- rv.setLayoutManager(new LinearLayoutManager(rv.getContext()));
- foodAdapter = new FoodAdapter();
- rv.setAdapter(foodAdapter);
-
- final TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
-// ProgressLayout headerView = new ProgressLayout(getContext());
- BezierLayout headerView = new BezierLayout(this);
- refreshLayout.setHeaderView(headerView);
-// refreshLayout.setFloatRefresh(false);
- refreshLayout.setPureScrollModeOn();
-// refreshLayout.setEnableOverlayRefreshView(false);
-// refreshLayout.setAutoLoadMore(true);
-
- refreshCard();
-
- }
-
- void refreshCard() {
- List foods = new ArrayList<>();
- foods.add(new Food("Preparing Salmon Steak Close Up", "BY VIKTOR HANACEK", R.drawable.food1, R.drawable.avatar0));
- foods.add(new Food("Fresh & Healthy Fitness Broccoli Pie with Basil", "BY VIKTOR HANACEK", R.drawable.food2, R.drawable.avatar1));
- foods.add(new Food("Enjoying a Tasty Burger", "BY VIKTOR HANACEK", R.drawable.food3, R.drawable.avatar2));
- foods.add(new Food("Fresh Strawberries and Blackberries in Little Bowl", "BY VIKTOR HANACEK", R.drawable.food4, R.drawable.avatar3));
- foods.add(new Food("Baked Healthy Fitness Broccoli Pie with Basil", "BY VIKTOR HANACEK", R.drawable.food5, R.drawable.avatar4));
- foodAdapter.setDataList(foods);
- }
-
- void loadMoreCard() {
- List foods = new ArrayList<>();
-// foods.add(new Food(R.drawable.food3));
-// foods.add(new Food(R.drawable.food2));
-// foods.add(new Food(R.drawable.food1));
- foodAdapter.addItems(foods);
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/MainActivity.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/MainActivity.java
deleted file mode 100644
index c5f077fac221524ebbb749005065d6c3f5f53a96..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/MainActivity.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.content.Intent;
-import android.support.v7.widget.Toolbar;
-import android.view.View;
-
-public class MainActivity extends BaseActivity implements View.OnClickListener {
-
- @Override
- public int setInflateId() {
- return R.layout.activity_main;
- }
-
- @Override
- public void init() {
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
- findViewById(R.id.bt_music).setOnClickListener(this);
- findViewById(R.id.bt_food).setOnClickListener(this);
- findViewById(R.id.bt_science).setOnClickListener(this);
- findViewById(R.id.bt_photo).setOnClickListener(this);
- findViewById(R.id.bt_story).setOnClickListener(this);
- findViewById(R.id.bt_enjoy).setOnClickListener(this);
- findViewById(R.id.bt_coordinate).setOnClickListener(this);
- findViewById(R.id.bt_test).setOnClickListener(this);
- findViewById(R.id.bt_normalView).setOnClickListener(this);
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.bt_music:
- startActivity(new Intent(MainActivity.this, MusicActivity.class));
- break;
- case R.id.bt_food:
- startActivity(new Intent(MainActivity.this, FoodActivity.class));
- break;
- case R.id.bt_science:
- startActivity(new Intent(MainActivity.this, ScienceActivity.class));
- break;
- case R.id.bt_photo:
- startActivity(new Intent(MainActivity.this, PhotoActivity.class));
- break;
- case R.id.bt_story:
- startActivity(new Intent(MainActivity.this, StoryActivity.class));
- break;
- case R.id.bt_enjoy:
- startActivity(new Intent(MainActivity.this, WebActivity.class));
- break;
- case R.id.bt_coordinate:
- startActivity(new Intent(MainActivity.this,CoordinateActivity.class));
- break;
- case R.id.bt_normalView:
- startActivity(new Intent(MainActivity.this,NormalViewActivity.class));
- break;
- case R.id.bt_test:
- startActivity(new Intent(MainActivity.this,TestActivity.class));
- break;
- }
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/MusicActivity.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/MusicActivity.java
deleted file mode 100644
index 474ad521972601218fc29c005b9c6761898f65f9..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/MusicActivity.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ListView;
-
-import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-import com.lcodecore.tkrefreshlayout.header.progresslayout.ProgressLayout;
-import com.lcodecore.twinklingrefreshlayout.adapter.MusicAdapter;
-import com.lcodecore.twinklingrefreshlayout.utils.ToastUtil;
-
-//TODO 有FixedHeader的界面fling有问题
-public class MusicActivity extends AppCompatActivity {
-
- private MusicAdapter adapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_music);
-
- Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
- mToolbar.setNavigationIcon(R.drawable.back);
- mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- finish();
- }
- });
-
- setupListView((ListView) findViewById(R.id.listView));
- }
-
- private void setupListView(ListView listView) {
- TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
- ProgressLayout headerView = new ProgressLayout(this);
- refreshLayout.setHeaderView(headerView);
- View exHeader = View.inflate(this, R.layout.header_music, null);
- refreshLayout.addFixedExHeader(exHeader);
- refreshLayout.setOverScrollRefreshShow(false);
-// refreshLayout.setFloatRefresh(true);
- adapter = new MusicAdapter();
- listView.setAdapter(adapter);
- adapter.refreshCard();
-
- exHeader.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- ToastUtil.show("fixed header clicked!");
- }
- });
-
- listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
- ToastUtil.show("item clicked!");
- }
- });
-
- refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
- @Override
- public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- adapter.refreshCard();
- refreshLayout.finishRefreshing();
- }
- }, 2000);
- }
-
- @Override
- public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- adapter.loadMoreCard();
- refreshLayout.finishLoadmore();
- }
- }, 2000);
- }
- });
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/NestedLayoutActivity.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/NestedLayoutActivity.java
deleted file mode 100644
index 9fe866865cc686f1801c8a524b47b4634a41395e..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/NestedLayoutActivity.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.StaggeredGridLayoutManager;
-import android.view.View;
-import android.view.WindowManager;
-
-import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-import com.lcodecore.tkrefreshlayout.header.bezierlayout.BezierLayout;
-import com.lcodecore.twinklingrefreshlayout.adapter.PhotoAdapter;
-import com.lcodecore.twinklingrefreshlayout.beans.Photo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Created by lcodecore on 2017/3/4.
- */
-
-public class NestedLayoutActivity extends AppCompatActivity {
- private PhotoAdapter photoAdapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_nested_layout);
-
- setupRecyclerView((RecyclerView) findViewById(R.id.recyclerview));
-
- findViewById(R.id.bt_back).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- finish();
- }
- });
-
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
- }
-
- private void setupRecyclerView(RecyclerView rv) {
- rv.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
- photoAdapter = new PhotoAdapter();
- rv.setAdapter(photoAdapter);
-
- final TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
-// ProgressLayout headerView = new ProgressLayout(this);
- BezierLayout headerView = new BezierLayout(this);
- refreshLayout.setHeaderView(headerView);
- refreshLayout.setMaxHeadHeight(140);
-// refreshLayout.setFloatRefresh(true);
-// refreshLayout.setPureScrollModeOn(true);
- refreshLayout.setOverScrollBottomShow(false);
- refreshLayout.setTargetView(rv);
-// refreshLayout.setAutoLoadMore(true);
-
-// addHeader();
- refreshCard();
-
-
- refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
- @Override
- public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- refreshCard();
- refreshLayout.finishRefreshing();
- }
- }, 2000);
- }
-
- @Override
- public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- loadMoreCard();
- refreshLayout.finishLoadmore();
- }
- }, 2000);
- }
- });
-
-// refreshLayout.startRefresh();
- }
-
- void refreshCard() {
- List photos = new ArrayList<>();
-// foods.add(new Food("Preparing Salmon Steak Close Up","BY VIKTOR HANACEK",R.drawable.food1,R.drawable.avatar0));
-// foods.add(new Food("Fresh & Healthy Fitness Broccoli Pie with Basil","BY VIKTOR HANACEK",R.drawable.food2,R.drawable.avatar1));
-// foods.add(new Food("Enjoying a Tasty Burger","BY VIKTOR HANACEK",R.drawable.food3,R.drawable.avatar2));
-// foods.add(new Food("Fresh Strawberries and Blackberries in Little Bowl","BY VIKTOR HANACEK",R.drawable.food4,R.drawable.avatar3));
-// foods.add(new Food("Baked Healthy Fitness Broccoli Pie with Basil","BY VIKTOR HANACEK",R.drawable.food5,R.drawable.avatar4));
- photos.add(new Photo("chest nut", R.drawable.photo1));
- photos.add(new Photo("fish", R.drawable.photo2));
- photos.add(new Photo("cat", R.drawable.photo10));
- photos.add(new Photo("guitar", R.drawable.photo3));
- photos.add(new Photo("common-hazel", R.drawable.photo4));
- photos.add(new Photo("cherry", R.drawable.photo5));
- photos.add(new Photo("flower details", R.drawable.photo6));
- photos.add(new Photo("tree", R.drawable.photo7));
- photos.add(new Photo("blue berries", R.drawable.photo8));
- photos.add(new Photo("snow man", R.drawable.photo9));
- photoAdapter.setDataList(photos);
- }
-
- void loadMoreCard() {
- List photos = new ArrayList<>();
- photos.add(new Photo("chest nut", R.drawable.photo1));
- photos.add(new Photo("fish", R.drawable.photo2));
- photos.add(new Photo("cat", R.drawable.photo10));
- photos.add(new Photo("guitar", R.drawable.photo3));
- photos.add(new Photo("common-hazel", R.drawable.photo4));
- photos.add(new Photo("cherry", R.drawable.photo5));
- photos.add(new Photo("flower details", R.drawable.photo6));
- photos.add(new Photo("tree", R.drawable.photo7));
- photos.add(new Photo("blue berries", R.drawable.photo8));
- photos.add(new Photo("snow man", R.drawable.photo9));
- //chest nut cat and fish guitar common-hazel cherry flower details tree
- //blue berries snow man
-// foods.add(new Food(R.drawable.food3));
-// foods.add(new Food(R.drawable.food2));
-// foods.add(new Food(R.drawable.food1));
- photoAdapter.addItems(photos);
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/NormalViewActivity.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/NormalViewActivity.java
deleted file mode 100644
index 7c5ea4d7aca9f2ce71f975bc0f0403d8e8fc3bb3..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/NormalViewActivity.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-
-/**
- * Created by lcodecore on 2017/4/6.
- */
-
-public class NormalViewActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_normalview);
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/PhotoActivity.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/PhotoActivity.java
deleted file mode 100644
index 75c465324af0e98b0aa992e410a77dab195b3ec1..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/PhotoActivity.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.os.Handler;
-import android.support.v7.app.AppCompatActivity;
-import android.os.Bundle;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.StaggeredGridLayoutManager;
-import android.view.View;
-import android.view.WindowManager;
-
-import com.lcodecore.tkrefreshlayout.header.bezierlayout.BezierLayout;
-import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-import com.lcodecore.twinklingrefreshlayout.adapter.PhotoAdapter;
-import com.lcodecore.twinklingrefreshlayout.beans.Photo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PhotoActivity extends AppCompatActivity {
- private PhotoAdapter photoAdapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_photo);
-
- setupRecyclerView((RecyclerView) findViewById(R.id.recyclerview));
-
- findViewById(R.id.bt_back).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- finish();
- }
- });
-
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
- }
-
- private void setupRecyclerView(RecyclerView rv) {
- rv.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
- photoAdapter = new PhotoAdapter();
- rv.setAdapter(photoAdapter);
-
- final TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
-// ProgressLayout headerView = new ProgressLayout(this);
- BezierLayout headerView = new BezierLayout(this);
- refreshLayout.setHeaderView(headerView);
- refreshLayout.setMaxHeadHeight(140);
-// refreshLayout.setFloatRefresh(true);
-// refreshLayout.setPureScrollModeOn(true);
- refreshLayout.setOverScrollBottomShow(false);
-// refreshLayout.setAutoLoadMore(true);
-
-// addHeader();
- refreshCard();
- findViewById(R.id.ib_refresh).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- refreshLayout.startRefresh();
- }
- });
-
- refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
- @Override
- public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- refreshCard();
- refreshLayout.finishRefreshing();
- }
- }, 2000);
- }
-
- @Override
- public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- loadMoreCard();
- refreshLayout.finishLoadmore();
- }
- }, 2000);
- }
- });
-
-// refreshLayout.startRefresh();
- }
-
- void refreshCard() {
- List photos = new ArrayList<>();
-// foods.add(new Food("Preparing Salmon Steak Close Up","BY VIKTOR HANACEK",R.drawable.food1,R.drawable.avatar0));
-// foods.add(new Food("Fresh & Healthy Fitness Broccoli Pie with Basil","BY VIKTOR HANACEK",R.drawable.food2,R.drawable.avatar1));
-// foods.add(new Food("Enjoying a Tasty Burger","BY VIKTOR HANACEK",R.drawable.food3,R.drawable.avatar2));
-// foods.add(new Food("Fresh Strawberries and Blackberries in Little Bowl","BY VIKTOR HANACEK",R.drawable.food4,R.drawable.avatar3));
-// foods.add(new Food("Baked Healthy Fitness Broccoli Pie with Basil","BY VIKTOR HANACEK",R.drawable.food5,R.drawable.avatar4));
- photos.add(new Photo("chest nut", R.drawable.photo1));
- photos.add(new Photo("fish", R.drawable.photo2));
- photos.add(new Photo("cat", R.drawable.photo10));
- photos.add(new Photo("guitar", R.drawable.photo3));
- photos.add(new Photo("common-hazel", R.drawable.photo4));
- photos.add(new Photo("cherry", R.drawable.photo5));
- photos.add(new Photo("flower details", R.drawable.photo6));
- photos.add(new Photo("tree", R.drawable.photo7));
- photos.add(new Photo("blue berries", R.drawable.photo8));
- photos.add(new Photo("snow man", R.drawable.photo9));
- photoAdapter.setDataList(photos);
- }
-
- void loadMoreCard() {
- List photos = new ArrayList<>();
- photos.add(new Photo("chest nut", R.drawable.photo1));
- photos.add(new Photo("fish", R.drawable.photo2));
- photos.add(new Photo("cat", R.drawable.photo10));
- photos.add(new Photo("guitar", R.drawable.photo3));
- photos.add(new Photo("common-hazel", R.drawable.photo4));
- photos.add(new Photo("cherry", R.drawable.photo5));
- photos.add(new Photo("flower details", R.drawable.photo6));
- photos.add(new Photo("tree", R.drawable.photo7));
- photos.add(new Photo("blue berries", R.drawable.photo8));
- photos.add(new Photo("snow man", R.drawable.photo9));
- //chest nut cat and fish guitar common-hazel cherry flower details tree
- //blue berries snow man
-// foods.add(new Food(R.drawable.food3));
-// foods.add(new Food(R.drawable.food2));
-// foods.add(new Food(R.drawable.food1));
- photoAdapter.addItems(photos);
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/ScienceActivity.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/ScienceActivity.java
deleted file mode 100644
index 447a63e9d9d2b54679181c603516e99067844d37..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/ScienceActivity.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v7.app.AppCompatActivity;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.GridView;
-
-import com.lcodecore.tkrefreshlayout.footer.LoadingView;
-import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-import com.lcodecore.tkrefreshlayout.header.SinaRefreshView;
-import com.lcodecore.twinklingrefreshlayout.adapter.ScienceAdapter;
-import com.lcodecore.twinklingrefreshlayout.utils.ToastUtil;
-
-public class ScienceActivity extends AppCompatActivity {
-
- private ScienceAdapter adapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_science);
- setupGridView((GridView) findViewById(R.id.gridView));
-
- findViewById(R.id.bt_back).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- finish();
- }
- });
- }
-
- private void setupGridView(GridView gridView) {
- final TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
- SinaRefreshView headerView = new SinaRefreshView(this);
- headerView.setArrowResource(R.drawable.arrow);
- headerView.setTextColor(0xff745D5C);
-// TextHeaderView headerView = (TextHeaderView) View.inflate(this,R.layout.header_tv,null);
- refreshLayout.setHeaderView(headerView);
-
- LoadingView loadingView = new LoadingView(this);
- refreshLayout.setBottomView(loadingView);
-
- adapter = new ScienceAdapter();
- gridView.setAdapter(adapter);
- adapter.refreshCard();
-
- gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
- ToastUtil.show("item clicked!");
- }
- });
-
- refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
- @Override
- public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- adapter.refreshCard();
- refreshLayout.finishRefreshing();
- }
- }, 2000);
- }
-
- @Override
- public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- adapter.loadMoreCard();
- refreshLayout.finishLoadmore();
- }
- }, 2000);
- }
- });
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/StoryActivity.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/StoryActivity.java
deleted file mode 100644
index c29227d415984e6403fa3c9db3cf41ed69624767..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/StoryActivity.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.os.Handler;
-import android.support.v7.app.AppCompatActivity;
-import android.os.Bundle;
-
-import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-import com.lcodecore.tkrefreshlayout.footer.LoadingView;
-import com.lcodecore.tkrefreshlayout.header.progresslayout.ProgressLayout;
-
-public class StoryActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_story);
-
- final TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
-// ProgressLayout header = new ProgressLayout(this);
-// refreshLayout.setHeaderView(header);
-// refreshLayout.setFloatRefresh(true);
- refreshLayout.setOverScrollRefreshShow(false);
- refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
- @Override
- public void onRefresh(TwinklingRefreshLayout refreshLayout1) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- refreshLayout.finishRefreshing();
- }
- }, 4000);
- }
-
- @Override
- public void onLoadMore(final TwinklingRefreshLayout refreshLayout1) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- refreshLayout.finishLoadmore();
- }
- }, 4000);
- }
- });
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/TestActivity.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/TestActivity.java
deleted file mode 100644
index e31fdffe8d2ff82b82643aa0777cc39a5523531f..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/TestActivity.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v7.app.AppCompatActivity;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.Button;
-import android.widget.GridView;
-
-import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-import com.lcodecore.tkrefreshlayout.footer.LoadingView;
-import com.lcodecore.tkrefreshlayout.header.SinaRefreshView;
-import com.lcodecore.twinklingrefreshlayout.adapter.ScienceAdapter;
-import com.lcodecore.twinklingrefreshlayout.utils.ToastUtil;
-
-/**
- * Created by lcodecore on 2017/3/27.
- */
-
-public class TestActivity extends AppCompatActivity implements View.OnClickListener {
-
- private ScienceAdapter adapter;
- private TwinklingRefreshLayout refreshLayout;
-
- private TestButton toggle_enableLoadmore, toggle_pureScrollMode_on, toggle_overScrollTopShow, toggle_osFooterShow, toggle_enableOverScroll, toggle_enableKeepIView,
- toggle_showRefreshingWhenOverScroll, toggle_showLoadingWhenOverScroll, toggle_floatRefresh, toggle_autoLoadMore,toggle_enableRefresh;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_test);
- setupGridView((GridView) findViewById(R.id.gridView));
-
- findViewById(R.id.bt_back).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- finish();
- }
- });
-
- toggle_enableLoadmore = new TestButton(R.id.toggle_enableLoadmore, "enableLoadmore", true);
- toggle_pureScrollMode_on = new TestButton(R.id.toggle_pureScrollMode_on, "pureScrollMode_on", false);
- toggle_overScrollTopShow = new TestButton(R.id.toggle_overScrollTopShow, "overScrollTopShow", true);
- toggle_osFooterShow = new TestButton(R.id.toggle_osFooterShow, "osFooterShow", true);
- toggle_enableOverScroll = new TestButton(R.id.toggle_enableOverScroll, "enableOverScroll", true);
- toggle_enableKeepIView = new TestButton(R.id.toggle_enableKeepIView, "enableKeepIView", true);
- toggle_showRefreshingWhenOverScroll = new TestButton(R.id.toggle_showRefreshingWhenOverScroll, "showRefreshingWhenOS", true);
- toggle_showLoadingWhenOverScroll = new TestButton(R.id.toggle_showLoadingWhenOverScroll, "showLoadingWhenOS", true);
- toggle_floatRefresh = new TestButton(R.id.toggle_floatRefresh, "floatRefresh", false);
- toggle_autoLoadMore = new TestButton(R.id.toggle_autoLoadMore, "autoLoadMore", false);
- toggle_enableRefresh = new TestButton(R.id.toggle_enableRefresh,"enableRefresh",true);
- }
-
- private void setupGridView(GridView gridView) {
- refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
- SinaRefreshView headerView = new SinaRefreshView(this);
- headerView.setArrowResource(R.drawable.arrow);
- headerView.setTextColor(0xff745D5C);
-// TextHeaderView headerView = (TextHeaderView) View.inflate(this,R.layout.header_tv,null);
- refreshLayout.setHeaderView(headerView);
-
- LoadingView loadingView = new LoadingView(this);
- refreshLayout.setBottomView(loadingView);
-
- adapter = new ScienceAdapter();
- gridView.setAdapter(adapter);
- adapter.refreshCard();
-
- gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
- ToastUtil.show("item clicked!");
- }
- });
-
- refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
- @Override
- public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- adapter.refreshCard();
- refreshLayout.finishRefreshing();
- }
- }, 2000);
- }
-
- @Override
- public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- adapter.loadMoreCard();
- refreshLayout.finishLoadmore();
- }
- }, 2000);
- }
- });
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.toggle_enableLoadmore:
- toggle_enableLoadmore.toggle();
- refreshLayout.setEnableLoadmore(toggle_enableLoadmore.flag);
- break;
- case R.id.toggle_pureScrollMode_on:
- toggle_pureScrollMode_on.toggle();
- refreshLayout.setPureScrollModeOn();
- break;
- case R.id.toggle_overScrollTopShow:
- toggle_overScrollTopShow.toggle();
- refreshLayout.setOverScrollTopShow(toggle_overScrollTopShow.flag);
- break;
- case R.id.toggle_osFooterShow:
- toggle_osFooterShow.toggle();
- refreshLayout.setOverScrollBottomShow(toggle_osFooterShow.flag);
- break;
- case R.id.toggle_enableOverScroll:
- toggle_enableOverScroll.toggle();
- refreshLayout.setEnableOverScroll(toggle_enableOverScroll.flag);
- break;
- case R.id.toggle_enableKeepIView:
- toggle_enableKeepIView.toggle();
- refreshLayout.setEnableKeepIView(toggle_enableKeepIView.flag);
- break;
- case R.id.toggle_showRefreshingWhenOverScroll:
- toggle_showRefreshingWhenOverScroll.toggle();
- refreshLayout.showRefreshingWhenOverScroll(toggle_showRefreshingWhenOverScroll.flag);
- break;
- case R.id.toggle_showLoadingWhenOverScroll:
- toggle_showLoadingWhenOverScroll.toggle();
- refreshLayout.showLoadingWhenOverScroll(toggle_showLoadingWhenOverScroll.flag);
- break;
- case R.id.toggle_floatRefresh:
- toggle_floatRefresh.toggle();
- refreshLayout.setFloatRefresh(toggle_floatRefresh.flag);
- break;
- case R.id.toggle_autoLoadMore:
- toggle_autoLoadMore.toggle();
- refreshLayout.setAutoLoadMore(toggle_autoLoadMore.flag);
- break;
- case R.id.toggle_enableRefresh:
- toggle_enableRefresh.toggle();
- refreshLayout.setEnableRefresh(toggle_enableRefresh.flag);
- }
- }
-
- class TestButton {
- private Button button;
- private boolean flag;
- private String text;
-
- public TestButton(int id, String text, boolean flag) {
- button = (Button) findViewById(id);
- this.text = text;
- this.flag = flag;
- button.setOnClickListener(TestActivity.this);
- button.setText(text + "->" + flag);
- }
-
- public void toggle() {
- flag = !flag;
- button.setText(text + "->" + flag);
- }
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/TextHeaderView.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/TextHeaderView.java
deleted file mode 100644
index 7632931563b50eea6307b5564d2183946bba30ef..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/TextHeaderView.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.TextView;
-
-import com.lcodecore.tkrefreshlayout.IHeaderView;
-import com.lcodecore.tkrefreshlayout.OnAnimEndListener;
-
-/**
- * Created by lcodecore on 2016/10/1.
- */
-
-public class TextHeaderView extends TextView implements IHeaderView {
-
-
- public TextHeaderView(Context context) {
- super(context);
- }
-
- public TextHeaderView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public TextHeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @Override
- public View getView() {
- return this;
- }
-
- @Override
- public void onPullingDown(float fraction, float maxHeadHeight, float headHeight) {
- if (fraction < 1f) setText("下拉刷新");
- if (fraction > 1f) setText("释放刷新");
- }
-
- @Override
- public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) {
- if (fraction < 1f) setText("下拉刷新");
- }
-
- @Override
- public void startAnim(float maxHeadHeight, float headHeight) {
- setText("正在刷新");
- }
-
- @Override
- public void onFinish(OnAnimEndListener listener) {
- listener.onAnimEnd();
- }
-
- @Override
- public void reset() {
- setText("下拉刷新");
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/TkApplication.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/TkApplication.java
deleted file mode 100644
index 0f81ebfc1fa305b8f341d2fbda806ccec83f79c8..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/TkApplication.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.app.Application;
-import android.content.Context;
-import android.os.StrictMode;
-
-import com.github.moduth.blockcanary.BlockCanary;
-import com.github.moduth.blockcanary.BlockCanaryContext;
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-import com.lcodecore.tkrefreshlayout.footer.BallPulseView;
-import com.lcodecore.tkrefreshlayout.header.SinaRefreshView;
-import com.squareup.leakcanary.LeakCanary;
-
-import static android.os.Build.VERSION.SDK_INT;
-import static android.os.Build.VERSION_CODES.GINGERBREAD;
-
-/**
- * Created by lcodecore on 2016/12/4.
- */
-
-public class TkApplication extends Application {
-
- public static Context appContext;
-
- @Override
- public void onCreate() {
- super.onCreate();
-
- appContext = this;
-
- if (LeakCanary.isInAnalyzerProcess(this)) {
- return;
- }
- enabledStrictMode();
- LeakCanary.install(this);
-
- StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyDeath().build());
- StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyDeath().build());
-
- BlockCanary.install(this,new AppBlockCanaryContext()).start();
-
-// TwinklingRefreshLayout.setDefaultHeader(SinaRefreshView.class.getName());
-// TwinklingRefreshLayout.setDefaultFooter(BallPulseView.class.getName());
- }
-
- private class AppBlockCanaryContext extends BlockCanaryContext{}
-
- private void enabledStrictMode() {
- if (SDK_INT >= GINGERBREAD) {
- StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() //
- .detectAll() //
- .penaltyLog() //
- .penaltyDeath() //
- .build());
- }
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/WebActivity.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/WebActivity.java
deleted file mode 100644
index 293caa871df54854af47f49d63100a9e67e168fa..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/WebActivity.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout;
-
-import android.annotation.SuppressLint;
-import android.os.Handler;
-import android.support.v7.app.AppCompatActivity;
-import android.os.Bundle;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.webkit.WebView;
-
-import com.lcodecore.tkrefreshlayout.header.progresslayout.ProgressLayout;
-import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-
-public class WebActivity extends AppCompatActivity {
-
- private WebView mWebView;
-
- @SuppressLint("SetJavaScriptEnabled")
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_web);
-
- TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refreshLayout);
- ProgressLayout header = new ProgressLayout(this);
- refreshLayout.setHeaderView(header);
- refreshLayout.setFloatRefresh(true);
- refreshLayout.setOverScrollRefreshShow(false);
- refreshLayout.setHeaderHeight(140);
- refreshLayout.setMaxHeadHeight(240);
- refreshLayout.setOverScrollHeight(200);
- refreshLayout.setEnableLoadmore(false);
- header.setColorSchemeResources(R.color.Blue, R.color.Orange, R.color.Yellow, R.color.Green);
-// header.setColorSchemeColors(0xff4674e7,0xff0ba62c);
-
- mWebView = (WebView) findViewById(R.id.webView);
- mWebView.getSettings().setJavaScriptEnabled(true);
- mWebView.loadUrl("https://dribbble.com/shots");
-
- refreshLayout.startRefresh();
- refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
- @Override
- public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- refreshLayout.finishRefreshing();
- }
- }, 4000);
- }
- });
- }
-
- @Override
- protected void onDestroy() {
- destroyWebView();
- super.onDestroy();
- }
-
- /**
- * 解决WebView持有mContext导致的内存泄漏问题
- */
- private void destroyWebView() {
- if (mWebView != null) {
- ViewParent parent = mWebView.getParent();
- if (parent != null) ((ViewGroup) parent).removeView(mWebView);
- mWebView.stopLoading();
- mWebView.getSettings().setJavaScriptEnabled(false);
- mWebView.clearHistory();
- mWebView.clearView();
- mWebView.removeAllViews();
- try {
- mWebView.destroy();
- } catch (Throwable e) {
- }
- }
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/FoodAdapter.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/FoodAdapter.java
deleted file mode 100644
index 5d071613abc23a4d5c23a7d62fb6d476976f6f46..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/FoodAdapter.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.adapter;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.lcodecore.twinklingrefreshlayout.R;
-import com.lcodecore.twinklingrefreshlayout.adapter.base.BaseRecyclerAdapter;
-import com.lcodecore.twinklingrefreshlayout.adapter.base.CommonHolder;
-import com.lcodecore.twinklingrefreshlayout.beans.Food;
-import com.lcodecore.twinklingrefreshlayout.utils.ToastUtil;
-import com.lcodecore.twinklingrefreshlayout.views.CircleImageView;
-
-import butterknife.Bind;
-
-/**
- * Created by lcodecore on 2016/12/6.
- */
-
-public class FoodAdapter extends BaseRecyclerAdapter {
- @Override
- public CommonHolder setViewHolder(ViewGroup parent) {
- return new CardHolder(parent.getContext(), parent);
- }
-
- class CardHolder extends CommonHolder {
-
- @Bind(R.id.avatar)
- CircleImageView avatar;
-
- @Bind(R.id.tv_food)
- TextView tv_food;
-
- @Bind(R.id.tv_info)
- TextView tv_info;
-
- @Bind(R.id.iv_food)
- ImageView iv_food;
-
- public CardHolder(Context context, ViewGroup root) {
- super(context, root, R.layout.item_food);
- }
-
- @Override
- public void bindData(Food food) {
- avatar.setImageResource(food.avatar_id);
- iv_food.setImageResource(food.imageSrc);
- tv_food.setText(food.title);
- tv_info.setText(food.info);
-
- itemView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- ToastUtil.show("item clicked!");
- }
- });
- }
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/LoopViewPagerAdapter.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/LoopViewPagerAdapter.java
deleted file mode 100644
index a92a57e3bdacfc94a9377fbe1c222d0c3ebfffa3..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/LoopViewPagerAdapter.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.adapter;
-
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.support.v4.view.ViewPager;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.lcodecore.twinklingrefreshlayout.R;
-import com.lcodecore.twinklingrefreshlayout.adapter.base.BaseLoopPagerAdapter;
-import com.lcodecore.twinklingrefreshlayout.beans.Card;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class LoopViewPagerAdapter extends BaseLoopPagerAdapter {
-
- private final List mHeroes;
-
- private final ViewGroup mIndicators;
-
- private int mLastPosition;
-
- public LoopViewPagerAdapter(ViewPager viewPager, ViewGroup indicators) {
- super(viewPager);
- mIndicators = indicators;
- mHeroes = new ArrayList<>();
- }
-
- public void setList(List heroes) {
- mHeroes.clear();
- mHeroes.addAll(heroes);
- initIndicators();
- notifyDataSetChanged();
- }
-
- /**
- * oh shit! An indicator view is badly needed!
- * this shit have no animation at all.
- */
- private void initIndicators() {
- if (mIndicators.getChildCount() != mHeroes.size() && mHeroes.size() > 1) {
- mIndicators.removeAllViews();
- Resources res = mIndicators.getResources();
- int size = res.getDimensionPixelOffset(R.dimen.indicator_size);
- int margin = res.getDimensionPixelOffset(R.dimen.indicator_margin);
- for (int i = 0; i < getPagerCount(); i++) {
- ImageView indicator = new ImageView(mIndicators.getContext());
- indicator.setAlpha(180);
- LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(size, size);
- lp.setMargins(margin, 0, 0, 0);
- lp.gravity = Gravity.CENTER;
- indicator.setLayoutParams(lp);
- Drawable drawable = res.getDrawable(R.drawable.selector_indicator);
- indicator.setImageDrawable(drawable);
- mIndicators.addView(indicator);
- }
- }
- }
-
- @Override
- public int getPagerCount() {
- return mHeroes.size();
- }
-
- @Override
- public Card getItem(int position) {
- return mHeroes.get(position);
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ViewHolder holder = null;
- if (convertView == null) {
- convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_viewpager, parent, false);
- holder = new ViewHolder();
- holder.ivBanner = (ImageView) convertView.findViewById(R.id.ivBanner);
- holder.tvName = (TextView) convertView.findViewById(R.id.tvName);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
- int picSrcId = mHeroes.get(position).imageSrc;
- holder.tvName.setText(mHeroes.get(position).info);
- holder.ivBanner.setImageResource(picSrcId);
- return convertView;
- }
-
- @Override
- public void onPageItemSelected(int position) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- mIndicators.getChildAt(mLastPosition).setActivated(false);
- mIndicators.getChildAt(position).setActivated(true);
- }
- mLastPosition = position;
- }
-
- public static class ViewHolder {
- ImageView ivBanner;
- TextView tvName;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/MusicAdapter.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/MusicAdapter.java
deleted file mode 100644
index dae6bb54c1e09d3fc0eea0171ca6e26745369ee2..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/MusicAdapter.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.adapter;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.lcodecore.twinklingrefreshlayout.R;
-import com.lcodecore.twinklingrefreshlayout.beans.Card;
-import com.lcodecore.twinklingrefreshlayout.views.CircleImageView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Created by lcodecore on 2016/12/6.
- */
-
-public class MusicAdapter extends BaseAdapter {
-
- private List cards = new ArrayList<>();
-
- @Override
- public int getCount() {
- return cards.size();
- }
-
- @Override
- public Card getItem(int position) {
- return cards.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final MusicAdapter.ViewHolder holder;
- if (convertView == null) {
- convertView = View.inflate(parent.getContext(), R.layout.item_music, null);
- holder = new MusicAdapter.ViewHolder(convertView);
- convertView.setTag(holder);
- } else {
- holder = (MusicAdapter.ViewHolder) convertView.getTag();
- }
-
- holder.tv_title.setText(cards.get(position).title);
- holder.tv_subTitle.setText(cards.get(position).info);
- holder.mImageView.setImageResource(cards.get(position).imageSrc);
-
- return convertView;
- }
-
- class ViewHolder {
- final CircleImageView mImageView;
- final TextView tv_title;
- final TextView tv_subTitle;
-
- ViewHolder(View view) {
- mImageView = (CircleImageView) view.findViewById(R.id.avatar);
- tv_title = (TextView) view.findViewById(R.id.tv_song);
- tv_subTitle = (TextView) view.findViewById(R.id.tv_singer);
- }
- }
-
- public void refreshCard(){
- cards.clear();
- cards.add(new Card("What Do You Mean?", "Justin Bieber", R.drawable.avatar1));
- cards.add(new Card("Secret Garden", "Song From A Secret Garden", R.drawable.avatar2));
- cards.add(new Card("Moves Like Jagger","Maroon 5",R.drawable.avatar3));
- cards.add(new Card("Work Hard, Play Hard","Wiz Khalifa",R.drawable.avatar4));
- cards.add(new Card("See You Again","Charlie Puth",R.drawable.avatar7));
- cards.add(new Card("Love The Way You Lie (Part Ii)","Rihanna",R.drawable.avatar5));
- cards.add(new Card("Call Me Maybe","Carly Rae Jepsen",R.drawable.avatar9));
- cards.add(new Card("Let It Go","Demi Lovato",R.drawable.avatar8));
- notifyDataSetChanged();
- }
-
- public void loadMoreCard(){
- cards.add(new Card("You Raise Me Up","Westlife",R.drawable.avatar6));
- cards.add(new Card("See You Again","Charlie Puth",R.drawable.avatar7));
- cards.add(new Card("Love Story","Taylor Swift",R.drawable.avatar0));
- cards.add(new Card("Let It Go","Demi Lovato",R.drawable.avatar8));
- cards.add(new Card("Secret Garden", "Song From A Secret Garden", R.drawable.avatar2));
- cards.add(new Card("Call Me Maybe","Carly Rae Jepsen",R.drawable.avatar9));
- notifyDataSetChanged();
- }
-
- public void addCard() {
- cards.add(new Card("What Do You Mean?", "Justin Bieber", R.drawable.avatar1));
- cards.add(new Card("Secret Garden", "Song From A Secret Garden", R.drawable.avatar2));
- cards.add(new Card("Moves Like Jagger","Maroon 5",R.drawable.avatar3));
- cards.add(new Card("Work Hard, Play Hard","Wiz Khalifa",R.drawable.avatar4));
- cards.add(new Card("Love The Way You Lie (Part Ii)","Rihanna",R.drawable.avatar5));
- cards.add(new Card("You Raise Me Up","Westlife",R.drawable.avatar6));
- cards.add(new Card("See You Again","Charlie Puth",R.drawable.avatar7));
- cards.add(new Card("Let It Go","Demi Lovato",R.drawable.avatar8));
- cards.add(new Card("Call Me Maybe","Carly Rae Jepsen",R.drawable.avatar9));
- //Love Story Taylor Swift
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/PhotoAdapter.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/PhotoAdapter.java
deleted file mode 100644
index 48129a28d9aa5a5497bcb779af0457ca432ca9a0..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/PhotoAdapter.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.adapter;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.lcodecore.twinklingrefreshlayout.R;
-import com.lcodecore.twinklingrefreshlayout.adapter.base.BaseRecyclerAdapter;
-import com.lcodecore.twinklingrefreshlayout.adapter.base.CommonHolder;
-import com.lcodecore.twinklingrefreshlayout.beans.Photo;
-import com.lcodecore.twinklingrefreshlayout.utils.ToastUtil;
-
-import butterknife.Bind;
-
-/**
- * Created by lcodecore on 2016/12/7.
- */
-
-public class PhotoAdapter extends BaseRecyclerAdapter {
- @Override
- public CommonHolder setViewHolder(ViewGroup parent) {
- return new CardHolder(parent.getContext(), parent);
- }
-
- class CardHolder extends CommonHolder {
-
- @Bind(R.id.tv_info)
- TextView tv_info;
-
- @Bind(R.id.iv_pic)
- ImageView iv_pic;
-
- public CardHolder(Context context, ViewGroup root) {
- super(context, root, R.layout.item_photo);
- }
-
- @Override
- public void bindData(Photo photo) {
- iv_pic.setImageResource(photo.imgSrc);
- tv_info.setText(photo.name);
-
- itemView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- ToastUtil.show("item clicked!");
- }
- });
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/ScienceAdapter.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/ScienceAdapter.java
deleted file mode 100644
index e5c30e4b6b16bdce5409396b08d1397c3de1c031..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/ScienceAdapter.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.adapter;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.lcodecore.twinklingrefreshlayout.R;
-import com.lcodecore.twinklingrefreshlayout.beans.Card;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Created by lcodecore on 2016/12/7.
- */
-
-public class ScienceAdapter extends BaseAdapter {
-
- private List cards = new ArrayList<>();
-
- @Override
- public int getCount() {
- return cards.size();
- }
-
- @Override
- public Card getItem(int position) {
- return cards.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final ViewHolder holder;
- if (convertView == null) {
- convertView = View.inflate(parent.getContext(), R.layout.item_science, null);
- holder = new ViewHolder(convertView);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
-
- holder.tv_name.setText(cards.get(position).title);
- holder.iv_cover.setImageResource(cards.get(position).imageSrc);
-
- return convertView;
- }
-
- class ViewHolder {
- final ImageView iv_cover;
- final TextView tv_name;
-
- ViewHolder(View view) {
- iv_cover = (ImageView) view.findViewById(R.id.iv_cover);
- tv_name = (TextView) view.findViewById(R.id.tv_name);
- }
- }
-
- public void refreshCard() {
- cards.clear();
- cards.add(new Card("genetics", "", R.drawable.science1));
- cards.add(new Card("globe", "", R.drawable.science2));
- cards.add(new Card("lab-flask-leaf", "", R.drawable.science3));
- cards.add(new Card("magnet", "", R.drawable.science4));
- cards.add(new Card("microscope", "", R.drawable.science5));
- cards.add(new Card("moon", "", R.drawable.science6));
- cards.add(new Card("telescope", "", R.drawable.science7));
- cards.add(new Card("satellite", "", R.drawable.science8));
- cards.add(new Card("Newtons-cradle", "", R.drawable.science9));
- cards.add(new Card("nuclear-symbol", "", R.drawable.science10));
- notifyDataSetChanged();
- }
-
- public void loadMoreCard() {
- cards.add(new Card("genetics", "", R.drawable.science1));
- cards.add(new Card("globe", "", R.drawable.science2));
- cards.add(new Card("lab-flask-leaf", "", R.drawable.science3));
- cards.add(new Card("magnet", "", R.drawable.science4));
- cards.add(new Card("microscope", "", R.drawable.science5));
- cards.add(new Card("moon", "", R.drawable.science6));
- cards.add(new Card("telescope", "", R.drawable.science7));
- cards.add(new Card("satellite", "", R.drawable.science8));
- cards.add(new Card("Newtons-cradle", "", R.drawable.science9));
- cards.add(new Card("nuclear-symbol", "", R.drawable.science10));
- notifyDataSetChanged();
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/ViewPagerHolder.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/ViewPagerHolder.java
deleted file mode 100644
index 05130977d0f76c8be787a496fedeab727827c1c0..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/ViewPagerHolder.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.adapter;
-
-import android.content.Context;
-import android.support.v4.view.ViewPager;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-
-import com.lcodecore.twinklingrefreshlayout.R;
-import com.lcodecore.twinklingrefreshlayout.adapter.base.CommonHolder;
-import com.lcodecore.twinklingrefreshlayout.beans.Card;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import butterknife.Bind;
-
-public class ViewPagerHolder extends CommonHolder {
- private LoopViewPagerAdapter viewPagerAdapter;
- private List cards = new ArrayList<>();
-
- @Bind(R.id.viewPager)
- ViewPager viewPager;
-
- @Bind(R.id.indicators)
- LinearLayout indicators;
-
- public ViewPagerHolder(Context context, ViewGroup root) {
- super(context, root, R.layout.layout_viewpager);
-
-// cards.add(new Card("二次元专题", "啊喂,别总想去四维空间啦",R.drawable.card_cover6));
-// cards.add(new Card("Music Player", "闻其名,余音绕梁",R.drawable.card_cover7));
-// cards.add(new Card("el", "剪纸人の唯美旅程",R.drawable.card_cover8));
-// cards.add(new Card("God of Light", "点亮世界之光",R.drawable.card_cover1));
-// cards.add(new Card("BlackLight", "做最纯粹的微博客户端",R.drawable.card_cover3));
- }
-
- @Override
- public void bindData(Void aVoid) {
-
- }
-
- @Override
- public void bindHeadData() {
- if(viewPager.getAdapter() == null){
- viewPagerAdapter = new LoopViewPagerAdapter(viewPager, indicators);
- viewPager.setAdapter(viewPagerAdapter);
- viewPager.addOnPageChangeListener(viewPagerAdapter);
- viewPagerAdapter.setList(cards);
- }/*else{
- viewPagerAdapter.setList(pics);
- }*/
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/BaseLoopPagerAdapter.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/BaseLoopPagerAdapter.java
deleted file mode 100644
index 1922f8624bd26c690447ccdacd8ed89914e7e92b..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/BaseLoopPagerAdapter.java
+++ /dev/null
@@ -1,240 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.adapter.base;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-public abstract class BaseLoopPagerAdapter extends PagerAdapter implements ViewPager.OnPageChangeListener, View.OnTouchListener, Runnable {
-
- private static final int DEFAULT_DELAY_MILLIS = 5000;
-
- private final ViewPager mViewPager;
-
- private final Handler mHandler;
-
- private final List mViews;
-
- private final List mList;
-
- private int mChildCount;
-
- private int mDelayMillis = DEFAULT_DELAY_MILLIS;
-
- private boolean mRunning;
-
- public BaseLoopPagerAdapter(ViewPager viewPager) {
- mHandler = new Handler(Looper.getMainLooper());
- mList = new ArrayList<>();
- mViews = new LinkedList<>();
-
- mViewPager = viewPager;
- mViewPager.setOnTouchListener(this);
- }
-
- /**
- * get the item count or pager count
- *
- * @return
- * @see #notifyDataSetChanged()
- */
- public abstract int getPagerCount();
-
- /**
- * get the item
- *
- * @param position
- * @return
- * @see #notifyDataSetChanged()
- */
- public abstract Object getItem(int position);
-
- /**
- * get the viewpager item view
- *
- * @param position
- * @param convertView
- * @param parent
- * @return
- * @see #instantiateItem(ViewGroup, int)
- */
- public abstract View getView(int position, View convertView, ViewGroup parent);
-
- /**
- * @see #onPageSelected(int)
- */
- public abstract void onPageItemSelected(int position);
-
- @Override
- public void notifyDataSetChanged() {
- int fixedCount = getPagerCount();
- if (fixedCount <= 0) {
- return;
- } else if (fixedCount == 1) {
- if (fixedCount != mList.size()) {
- mList.clear();
- mList.add(getItem(0));
- }
- if (fixedCount != mViews.size()) {
- mViews.clear();
- mViews.add(null);
- }
- } else if (fixedCount > 1) {
- if (fixedCount + 2 != mList.size()) {
- mList.clear();
- // add last element in position 0, add all, add first element in last position
- mList.add(getItem(fixedCount - 1));
- for (int i = 0; i < fixedCount; i++) {
- mList.add(getItem(i));
- }
- mList.add(getItem(0));
- }
-
- if (fixedCount + 2 != mViews.size()) {
- mViews.clear();
- for (int i = 0; i < mList.size(); i++) {
- mViews.add(null);
- }
- }
- }
- super.notifyDataSetChanged();
-
- // this is very important
- mChildCount = getCount();
-
- if (mViewPager.getCurrentItem() == 0 && mChildCount != 1) {
- mViewPager.setCurrentItem(1, false);
- }
-
- stop();
- start();
- }
-
- public void setDelayMillis(int delayMillis) {
- this.mDelayMillis = delayMillis;
- if (delayMillis <= 0) {
- mDelayMillis = DEFAULT_DELAY_MILLIS;
- }
- }
-
- /**
- * start loop
- */
- public void start() {
- if (!mRunning) {
- post();
- mRunning = true;
- }
- }
-
- /**
- * stop loop
- */
- public void stop() {
- if (mRunning) {
- mHandler.removeCallbacks(this);
- mRunning = false;
- }
- }
-
- @Override
- public final boolean onTouch(View v, MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- stop();
- } else if (event.getAction() == MotionEvent.ACTION_UP) {
- start();
- }
- return false;
- }
-
- @Override
- public final void run() {
- int currentPosition = mViewPager.getCurrentItem();
- if (0 < currentPosition && currentPosition < mList.size() - 1) {
-
- if (currentPosition + 1 == mList.size() - 1) {
- currentPosition = 1;
- } else {
- currentPosition++;
- }
- mViewPager.setCurrentItem(currentPosition, true);
-
- post();
- }
- }
-
- private void post() {
- mHandler.postDelayed(this, mDelayMillis);
- }
-
- @Override
- public final Object instantiateItem(ViewGroup container, int position) {
- int fixedPosition = 0;
- if (position == 0) {
- fixedPosition = getPagerCount() - 1;
- } else if (position == mList.size() - 1) {
- fixedPosition = 0;
- } else if (0 < position && position < mList.size() - 1) {
- fixedPosition = position - 1;
- }
- if (mViews.get(position) == null) {
- mViews.set(position, getView(fixedPosition, mViews.get(position), container));
- }
- container.addView(mViews.get(position));
- return mViews.get(position);
- }
-
- @Override
- public final int getItemPosition(Object object) {
- if (mChildCount > 0) {
- mChildCount--;
- return POSITION_NONE;
- }
- return super.getItemPosition(object);
- }
-
- @Override
- public final void destroyItem(ViewGroup container, int position, Object object) {
- container.removeView((View) object);
- }
-
- @Override
- public final int getCount() {
- return mList.size();
- }
-
- @Override
- public final boolean isViewFromObject(View view, Object object) {
- return view == object;
- }
-
- @Override
- public final void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- }
-
- @Override
- public final void onPageSelected(int position) {
- if (0 < position && position < mList.size() - 1) {
- onPageItemSelected(position - 1);
- }
- }
-
- @Override
- public final void onPageScrollStateChanged(int state) {
- if (state == ViewPager.SCROLL_STATE_IDLE) {
- if (mList.size() > 3) {
- if (mViewPager.getCurrentItem() == 0) {
- mViewPager.setCurrentItem(mList.size() - 2, false);
- } else if (mViewPager.getCurrentItem() == mList.size() - 1) {
- mViewPager.setCurrentItem(1, false);
- }
- }
- }
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/BaseRecyclerAdapter.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/BaseRecyclerAdapter.java
deleted file mode 100644
index 81d0ac953db51f1f87f2bde199e9f794781d130d..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/BaseRecyclerAdapter.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.adapter.base;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.content.Context;
-import android.support.v7.widget.RecyclerView;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.DecelerateInterpolator;
-
-import com.lcodecore.twinklingrefreshlayout.utils.DensityUtil;
-
-import java.util.ArrayList;
-import java.util.List;
-import butterknife.ButterKnife;
-/**
- * RecyclerView适配器基类
- */
-public abstract class BaseRecyclerAdapter extends RecyclerView.Adapter implements CommonHolder.OnNotifyChangeListener {
- private List dataList = new ArrayList<>();
- private boolean enableHead = false;
- CommonHolder headHolder;
- ViewGroup rootView;
- public final static int TYPE_HEAD = 0;
- public static final int TYPE_CONTENT = 1;
- @Override
- public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
- rootView = parent;
- //设置ViewHolder
- int type = getItemViewType(position);
- if (type == TYPE_HEAD) {
- return headHolder;
- } else {
- return setViewHolder(parent);
- }
- }
- @Override
- public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
-// runEnterAnimation(holder.itemView, position);
- //数据绑定
- if (enableHead) {
- if (position == 0) {
- ((CommonHolder) holder).bindHeadData();
- } else {
- ((CommonHolder) holder).bindData(dataList.get(position - 1));
- }
- } else {
- ((CommonHolder) holder).bindData(dataList.get(position));
- }
- ((CommonHolder) holder).setOnNotifyChangeListener(this);
- }
- public ViewGroup getRootView() {
- return rootView;
- }
- @Override
- public int getItemCount() {
- if (enableHead) {
- return dataList.size() + 1;
- }
- return dataList.size();
- }
- @Override
- public int getItemViewType(int position) {
- if (enableHead) {
- if (position == 0) {
- return TYPE_HEAD;
- } else {
- return TYPE_CONTENT;
- }
- } else {
- return TYPE_CONTENT;
- }
- }
- private int lastAnimatedPosition = -1;
- protected boolean animationsLocked = false;
- private boolean delayEnterAnimation = true;
- private void runEnterAnimation(View view, int position) {
- if (animationsLocked) return;
- if (position > lastAnimatedPosition) {
- lastAnimatedPosition = position;
- view.setTranslationY(DensityUtil.dip2px(view.getContext(), 100));//(position+1)*50f
- view.setAlpha(0.f);
- view.animate()
- .translationY(0).alpha(1.f)
- .setStartDelay(delayEnterAnimation ? 20 * (position) : 0)
- .setInterpolator(new DecelerateInterpolator(2.f))
- .setDuration(500)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- animationsLocked = true;
- }
- }).start();
- }
- }
- @Override
- public void onNotify() {
- //提供给CommonHolder方便刷新视图
- notifyDataSetChanged();
- }
- public void setDataList(List datas) {
- dataList.clear();
- if (null != datas) {
- dataList.addAll(datas);
- }
- notifyDataSetChanged();
- }
- public void clearDatas() {
- dataList.clear();
- notifyDataSetChanged();
- }
- /**
- * 添加数据到前面
- */
- public void addItemsAtFront(List datas) {
- if (null == datas) return;
- dataList.addAll(0, datas);
- notifyDataSetChanged();
- }
- /**
- * 添加数据到尾部
- */
- public void addItems(List datas) {
- if (null == datas) return;
- dataList.addAll(datas);
- notifyDataSetChanged();
- }
- /**
- * 添加单条数据
- */
- public void addItem(T data) {
- if (null == data) return;
- dataList.add(data);
- notifyDataSetChanged();
- }
- /**
- * 删除单条数据
- */
- public void deletItem(T data) {
- dataList.remove(data);
- Log.d("deletItem: ", dataList.remove(data) + "");
- notifyDataSetChanged();
- }
- /**
- * 设置是否显示head
- *
- * @param ifEnable 是否显示头部
- */
- public void setEnableHead(boolean ifEnable) {
- enableHead = ifEnable;
- }
- public void setHeadHolder(CommonHolder headHolder1) {
- enableHead = true;
- headHolder = headHolder1;
- }
- public void setHeadHolder(View itemView) {
- enableHead = true;
- headHolder = new HeadHolder(itemView);
- notifyItemInserted(0);
- }
- public CommonHolder getHeadHolder() {
- return headHolder;
- }
- /**
- * 子类重写实现自定义ViewHolder
- */
- public abstract CommonHolder setViewHolder(ViewGroup parent);
-
- public class HeadHolder extends CommonHolder {
- public HeadHolder(View itemView) {
- super(itemView);
- }
-
- public HeadHolder(Context context, ViewGroup root, int layoutRes) {
- super(context,root,layoutRes);
- }
-
- @Override
- public void bindData(Void aVoid) {//不用实现
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/CommonAdapter.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/CommonAdapter.java
deleted file mode 100644
index 1284b99beed29aebdc861467d92a06786a4a6036..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/CommonAdapter.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.adapter.base;
-
-import android.database.DataSetObservable;
-import android.database.DataSetObserver;
-import android.support.v7.widget.RecyclerView;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListAdapter;
-
-/**
- * Created by lcodecore on 2016/10/22.
- */
-
-public abstract class CommonAdapter implements ListAdapter {
- private final DataSetObservable mDataSetObservable = new DataSetObservable();
-
- public boolean hasStableIds() {
- return false;
- }
-
- public void registerDataSetObserver(DataSetObserver observer) {
- mDataSetObservable.registerObserver(observer);
- }
-
- public void unregisterDataSetObserver(DataSetObserver observer) {
- mDataSetObservable.unregisterObserver(observer);
- }
-
- /**
- * Notifies the attached observers that the underlying data has been changed
- * and any View reflecting the data set should refresh itself.
- */
- public void notifyDataSetChanged() {
- mDataSetObservable.notifyChanged();
- }
-
- /**
- * Notifies the attached observers that the underlying data is no longer valid
- * or available. Once invoked this adapter is no longer valid and should
- * not report further data set changes.
- */
- public void notifyDataSetInvalidated() {
- mDataSetObservable.notifyInvalidated();
- }
-
- public boolean areAllItemsEnabled() {
- return true;
- }
-
- public boolean isEnabled(int position) {
- return true;
- }
-
- public View getDropDownView(int position, View convertView, ViewGroup parent) {
- return getView(position, convertView, parent);
- }
-
- public int getItemViewType(int position) {
- return 0;
- }
-
- public int getViewTypeCount() {
- return 1;
- }
-
- public boolean isEmpty() {
- return getCount() == 0;
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/CommonHolder.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/CommonHolder.java
deleted file mode 100644
index 1ba4d4263db221472fdadddf0880531040f772c9..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/CommonHolder.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.adapter.base;
-
-import android.content.Context;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import butterknife.ButterKnife;
-/**
- * 聊天消息条目的基类
- * ViewHolder 与 Adapter 解耦
- */
-public abstract class CommonHolder extends RecyclerView.ViewHolder {
- public CommonHolder(Context context, ViewGroup root, int layoutRes) {
- super(LayoutInflater.from(context).inflate(layoutRes, root, false));
- ButterKnife.bind(this, itemView);
- }
- /**
- * 此适配器是为了能让详情页共用列表页的ViewHolder,一般情况无需重写该构造器
- */
- public CommonHolder(View itemView) {
- super(itemView);
- ButterKnife.bind(this, itemView);
- }
- public Context getContext() {
- return itemView.getContext();
- }
- /**
- * 用给定的 data 对 holder 的 view 进行赋值
- */
- public abstract void bindData(T t);
-
- public void bindHeadData(){}
- /**
- * 通知适配器更新布局
- */
- public interface OnNotifyChangeListener {
- void onNotify();
- }
- OnNotifyChangeListener listener;
- public void setOnNotifyChangeListener(OnNotifyChangeListener listener) {
- this.listener = listener;
- }
- public void notifyChange() {
- listener.onNotify();
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/utils/DensityUtil.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/utils/DensityUtil.java
deleted file mode 100644
index cc54dcdb753e99f7f0f941749beba2d303e09450..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/utils/DensityUtil.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.utils;
-
-import android.content.Context;
-import android.graphics.Point;
-import android.view.Display;
-import android.view.WindowManager;
-
-public class DensityUtil {
- private static int screenWidth = 0;
- private static int screenHeight = 0;
- public static int dip2px(Context var0, float var1) {
- float var2 = var0.getResources().getDisplayMetrics().density;
- return (int)(var1 * var2 + 0.5F);
- }
- public static int px2dip(Context var0, float var1) {
- float var2 = var0.getResources().getDisplayMetrics().density;
- return (int)(var1 / var2 + 0.5F);
- }
- public static int sp2px(Context var0, float var1) {
- float var2 = var0.getResources().getDisplayMetrics().scaledDensity;
- return (int)(var1 * var2 + 0.5F);
- }
- public static int px2sp(Context var0, float var1) {
- float var2 = var0.getResources().getDisplayMetrics().scaledDensity;
- return (int)(var1 / var2 + 0.5F);
- }
- public static int getScreenWidth(Context c) {
- if (screenWidth == 0) {
- WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
- Display display = wm.getDefaultDisplay();
- Point size = new Point();
- display.getSize(size);
- screenWidth = size.x;
- }
- return screenWidth;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/utils/ToastUtil.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/utils/ToastUtil.java
deleted file mode 100644
index 2c18988567741db47637d168238559b5476a4272..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/utils/ToastUtil.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.utils;
-
-import android.widget.Toast;
-
-import com.lcodecore.twinklingrefreshlayout.TkApplication;
-
-/**
- * Created by lcodecore on 2017/2/28.
- */
-
-public class ToastUtil {
- public static void show(String msg){
- Toast.makeText(TkApplication.appContext, msg, Toast.LENGTH_SHORT).show();
- }
-}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/views/CircleImageView.java b/app/src/main/java/com/lcodecore/twinklingrefreshlayout/views/CircleImageView.java
deleted file mode 100644
index f14d43caf4e784f6b180a7f536564d4e59c40ab7..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/views/CircleImageView.java
+++ /dev/null
@@ -1,307 +0,0 @@
-package com.lcodecore.twinklingrefreshlayout.views;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.BitmapShader;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.RectF;
-import android.graphics.Shader;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.support.annotation.ColorRes;
-import android.support.annotation.DrawableRes;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-
-import com.lcodecore.twinklingrefreshlayout.R;
-import com.lcodecore.twinklingrefreshlayout.utils.DensityUtil;
-
-/**
- * 头像的圆形处理工具
- **/
-
-public class CircleImageView extends ImageView {
-
- private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
-
- private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
- private static final int COLORDRAWABLE_DIMENSION = 2;
-
- private static final int DEFAULT_BORDER_WIDTH = 0;
- private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
- private static final boolean DEFAULT_BORDER_OVERLAY = false;
-
- private final RectF mDrawableRect = new RectF();
- private final RectF mBorderRect = new RectF();
-
- private final Matrix mShaderMatrix = new Matrix();
- private final Paint mBitmapPaint = new Paint();
- private final Paint mBorderPaint = new Paint();
-
- private int mBorderColor = DEFAULT_BORDER_COLOR;
- private int mBorderWidth = DEFAULT_BORDER_WIDTH;
-
- private Bitmap mBitmap;
- private BitmapShader mBitmapShader;
- private int mBitmapWidth;
- private int mBitmapHeight;
-
- private float mDrawableRadius;
- private float mBorderRadius;
-
- private ColorFilter mColorFilter;
-
- private boolean mReady;
- private boolean mSetupPending;
- private boolean mBorderOverlay;
-
- public CircleImageView(Context context) {
- super(context);
-
- init();
- }
-
- public CircleImageView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
-
- mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);
- mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);
- mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_border_overlay, DEFAULT_BORDER_OVERLAY);
-
- a.recycle();
-
- init();
- }
-
- private void init() {
- super.setScaleType(SCALE_TYPE);
- mReady = true;
-
- if (mSetupPending) {
- setup();
- mSetupPending = false;
- }
- }
-
- @Override
- public ScaleType getScaleType() {
- return SCALE_TYPE;
- }
-
- @Override
- public void setScaleType(ScaleType scaleType) {
- if (scaleType != SCALE_TYPE) {
- throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
- }
- }
-
- @Override
- public void setAdjustViewBounds(boolean adjustViewBounds) {
- if (adjustViewBounds) {
- throw new IllegalArgumentException("adjustViewBounds not supported.");
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- if (getDrawable() == null) {
- return;
- }
-
- canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);
- if (mBorderWidth != 0) {
- canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);
- }
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- setup();
- }
-
- public int getBorderColor() {
- return mBorderColor;
- }
-
- public void setBorderColor(int borderColor) {
- if (borderColor == mBorderColor) {
- return;
- }
-
- mBorderColor = borderColor;
- mBorderPaint.setColor(mBorderColor);
- invalidate();
- }
-
- public void setBorderColorResource(@ColorRes int borderColorRes) {
- setBorderColor(getContext().getResources().getColor(borderColorRes));
- }
-
- public int getBorderWidth() {
- return mBorderWidth;
- }
-
- public void setBorderWidth(int borderWidth) {
- if (borderWidth == mBorderWidth) {
- return;
- }
-
- mBorderWidth = borderWidth;
- setup();
- }
-
- public boolean isBorderOverlay() {
- return mBorderOverlay;
- }
-
- public void setBorderOverlay(boolean borderOverlay) {
- if (borderOverlay == mBorderOverlay) {
- return;
- }
-
- mBorderOverlay = borderOverlay;
- setup();
- }
-
- @Override
- public void setImageBitmap(Bitmap bm) {
- super.setImageBitmap(bm);
- mBitmap = bm;
- setup();
- }
-
- @Override
- public void setImageDrawable(Drawable drawable) {
- super.setImageDrawable(drawable);
- mBitmap = getBitmapFromDrawable(drawable);
- setup();
- }
-
- @Override
- public void setImageResource(@DrawableRes int resId) {
- super.setImageResource(resId);
- mBitmap = getBitmapFromDrawable(getDrawable());
- setup();
- }
-
- @Override
- public void setImageURI(Uri uri) {
- super.setImageURI(uri);
- mBitmap = getBitmapFromDrawable(getDrawable());
- setup();
- }
-
- @Override
- public void setColorFilter(ColorFilter cf) {
- if (cf == mColorFilter) {
- return;
- }
-
- mColorFilter = cf;
- mBitmapPaint.setColorFilter(mColorFilter);
- invalidate();
- }
-
- private Bitmap getBitmapFromDrawable(Drawable drawable) {
- if (drawable == null) {
- return null;
- }
-
- if (drawable instanceof BitmapDrawable) {
- return ((BitmapDrawable) drawable).getBitmap();
- }
-
- try {
- Bitmap bitmap;
-
- if (drawable instanceof ColorDrawable) {
- bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
- } else {
- if (!(drawable.getIntrinsicWidth() > 0) || !(drawable.getIntrinsicHeight() > 0)) {
- bitmap = Bitmap.createBitmap(DensityUtil.dip2px(getContext(), 40), DensityUtil.dip2px(getContext(),40), BITMAP_CONFIG);
- } else {
- bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
- }
- }
-
- Canvas canvas = new Canvas(bitmap);
- drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
- drawable.draw(canvas);
- return bitmap;
- } catch (OutOfMemoryError e) {
- return null;
- }
- }
-
- private void setup() {
- if (!mReady) {
- mSetupPending = true;
- return;
- }
-
- if (mBitmap == null) {
- return;
- }
-
- mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
-
- mBitmapPaint.setAntiAlias(true);
- mBitmapPaint.setShader(mBitmapShader);
-
- mBorderPaint.setStyle(Paint.Style.STROKE);
- mBorderPaint.setAntiAlias(true);
- mBorderPaint.setColor(mBorderColor);
- mBorderPaint.setStrokeWidth(mBorderWidth);
-
- mBitmapHeight = mBitmap.getHeight();
- mBitmapWidth = mBitmap.getWidth();
-
- mBorderRect.set(0, 0, getWidth(), getHeight());
- mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);
-
- mDrawableRect.set(mBorderRect);
- if (!mBorderOverlay) {
- mDrawableRect.inset(mBorderWidth, mBorderWidth);
- }
- mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);
-
- updateShaderMatrix();
- invalidate();
- }
-
- private void updateShaderMatrix() {
- float scale;
- float dx = 0;
- float dy = 0;
-
- mShaderMatrix.set(null);
-
- if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
- scale = mDrawableRect.height() / (float) mBitmapHeight;
- dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
- } else {
- scale = mDrawableRect.width() / (float) mBitmapWidth;
- dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
- }
-
- mShaderMatrix.setScale(scale, scale);
- mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
-
- mBitmapShader.setLocalMatrix(mShaderMatrix);
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-xhdpi/arrow.png b/app/src/main/res/drawable-xhdpi/arrow.png
deleted file mode 100644
index 3d7481c8f956895f6e832a2d0fe45f266bf34f56..0000000000000000000000000000000000000000
Binary files a/app/src/main/res/drawable-xhdpi/arrow.png and /dev/null differ
diff --git a/app/src/main/res/drawable/selector_indicator.xml b/app/src/main/res/drawable/selector_indicator.xml
deleted file mode 100644
index c349c20d933d68a137cf36830efd4209f631219e..0000000000000000000000000000000000000000
--- a/app/src/main/res/drawable/selector_indicator.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_coordinate.xml b/app/src/main/res/layout/activity_coordinate.xml
deleted file mode 100644
index 3129dbb9fd6613b71199bb8a4f6121a472c2d0ff..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/activity_coordinate.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_food.xml b/app/src/main/res/layout/activity_food.xml
deleted file mode 100644
index 67e143df44bdbe0d985b3df87e74dd20e6ffb888..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/activity_food.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
deleted file mode 100644
index b44266c25b5751cbffbebd6da309e28a21d47fb4..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_music.xml b/app/src/main/res/layout/activity_music.xml
deleted file mode 100644
index 65f68c7faab9c809727c99bdc8ca9318ac1669fe..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/activity_music.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_nested_layout.xml b/app/src/main/res/layout/activity_nested_layout.xml
deleted file mode 100644
index 4182ee83447c23515a3a0db665e7fe7ec0b1ab93..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/activity_nested_layout.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_normalview.xml b/app/src/main/res/layout/activity_normalview.xml
deleted file mode 100644
index eb970649e3dac44fe7ab41be7cb7f68c23820c28..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/activity_normalview.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_photo.xml b/app/src/main/res/layout/activity_photo.xml
deleted file mode 100644
index 96ad0f0bb7b1a56196d3e7329748c697bcabd969..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/activity_photo.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_science.xml b/app/src/main/res/layout/activity_science.xml
deleted file mode 100644
index 7a4275d893c38a768984bf80237f0579b4665483..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/activity_science.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_story.xml b/app/src/main/res/layout/activity_story.xml
deleted file mode 100644
index babd7666896075fc61b2f237c41fa5250935f2e1..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/activity_story.xml
+++ /dev/null
@@ -1,156 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_test.xml b/app/src/main/res/layout/activity_test.xml
deleted file mode 100644
index 0945215667a2704f8815aaa72e7ad14a2b990e97..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/activity_test.xml
+++ /dev/null
@@ -1,183 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_web.xml b/app/src/main/res/layout/activity_web.xml
deleted file mode 100644
index 448ec69b250f084c53a2b84a648a8a5a346b848f..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/activity_web.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml
deleted file mode 100644
index 6022aaca0aa783d34f4eafbea0d395058e3b16aa..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/content_main.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/header_music.xml b/app/src/main/res/layout/header_music.xml
deleted file mode 100644
index eed9da0718946b5d5e92a287cd8af609878fc9a5..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/header_music.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/header_tv.xml b/app/src/main/res/layout/header_tv.xml
deleted file mode 100644
index 193c2cd69dab90858ac0058c425f735d77f6f941..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/header_tv.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
diff --git a/app/src/main/res/layout/inc_toolbar.xml b/app/src/main/res/layout/inc_toolbar.xml
deleted file mode 100644
index 524a62b7948fae597f6b6ef5ffe13af0b1a57501..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/inc_toolbar.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_food.xml b/app/src/main/res/layout/item_food.xml
deleted file mode 100755
index 8d08f5a1e92b05eec6c4d05e17f26a782571295a..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/item_food.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_music.xml b/app/src/main/res/layout/item_music.xml
deleted file mode 100644
index 6ebdf51be3454d246c93e3bf30f28f0f351c6236..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/item_music.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_photo.xml b/app/src/main/res/layout/item_photo.xml
deleted file mode 100644
index da164f379ad590721aaeba8c0da33a74c7a24b38..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/item_photo.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_science.xml b/app/src/main/res/layout/item_science.xml
deleted file mode 100644
index 18dee9e925f59cc2c588cc625e46466c40e7be33..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/item_science.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_viewpager.xml b/app/src/main/res/layout/item_viewpager.xml
deleted file mode 100644
index f17d9cee42449d509bbb70b31362c8a91cba97bc..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/item_viewpager.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_viewpager.xml b/app/src/main/res/layout/layout_viewpager.xml
deleted file mode 100644
index dc561b0042f1e4f7e6a76497b14c45f1776ff1c4..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/layout_viewpager.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index cde69bcccec65160d92116f20ffce4fce0b5245c..0000000000000000000000000000000000000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index c133a0cbd379f5af6dbf1a899a0293ca5eccfad0..0000000000000000000000000000000000000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index bfa42f0e7b91d006d22352c9ff2f134e504e3c1d..0000000000000000000000000000000000000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 324e72cdd7480cb983fa1bcc7ce686e51ef87fe7..0000000000000000000000000000000000000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index aee44e138434630332d88b1680f33c4b24c70ab3..0000000000000000000000000000000000000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml
deleted file mode 100644
index 63fc816444614bd64f68a372d1f93211628ee51d..0000000000000000000000000000000000000000
--- a/app/src/main/res/values-w820dp/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- 64dp
-
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
deleted file mode 100644
index 7ea209f5b17758254dd20a05a8070c0f2ebf7906..0000000000000000000000000000000000000000
--- a/app/src/main/res/values/attrs.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
deleted file mode 100644
index f1d054e7a7c1d961aa0baf23815996cb8d7366b6..0000000000000000000000000000000000000000
--- a/app/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
- #353536
- #262626
- #e75946
-
- #ffffff
-
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
deleted file mode 100644
index 85b15246eeb67a1b220f039fa488e3567d7202a6..0000000000000000000000000000000000000000
--- a/app/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
- 16dp
- 16dp
-
- 240dp
- 6dp
- 6dp
-
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
deleted file mode 100644
index 592a813ad39888b83f27f3379f7ffef3c4fd1890..0000000000000000000000000000000000000000
--- a/app/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- TwinklingRefreshView
-
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
deleted file mode 100644
index 9f653666f94641f9ba5befc1cf2a87f520fdec82..0000000000000000000000000000000000000000
--- a/app/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/art/alipay.jpg b/art/alipay.jpg
deleted file mode 100644
index b785ae872d756f547adb79686817e7eb33fc5a1b..0000000000000000000000000000000000000000
Binary files a/art/alipay.jpg and /dev/null differ
diff --git a/art/app-debug.apk b/art/app-debug.apk
deleted file mode 100644
index 02e91581a24ee35fd506241fbe428c4a67855f3a..0000000000000000000000000000000000000000
Binary files a/art/app-debug.apk and /dev/null differ
diff --git a/art/gif2.gif b/art/gif2.gif
deleted file mode 100644
index 8346bc980d538e633a152a1e0a1eeee111fc1c3a..0000000000000000000000000000000000000000
Binary files a/art/gif2.gif and /dev/null differ
diff --git a/art/gif_gridview.gif b/art/gif_gridview.gif
deleted file mode 100644
index 3b3dae0a1e25c8bfb182eaff18318cc6410c3ff3..0000000000000000000000000000000000000000
Binary files a/art/gif_gridview.gif and /dev/null differ
diff --git a/art/gif_gridview.mp4 b/art/gif_gridview.mp4
deleted file mode 100644
index 84a2e6b6c159e112c1b1b87ee788603ea74ca34a..0000000000000000000000000000000000000000
Binary files a/art/gif_gridview.mp4 and /dev/null differ
diff --git a/art/gif_listview.gif b/art/gif_listview.gif
deleted file mode 100644
index 0b8b83e327b57902336802781ce393490686441d..0000000000000000000000000000000000000000
Binary files a/art/gif_listview.gif and /dev/null differ
diff --git a/art/gif_listview.mp4 b/art/gif_listview.mp4
deleted file mode 100644
index 25e7efd69ef791cea9e685644932975f21b4f7ff..0000000000000000000000000000000000000000
Binary files a/art/gif_listview.mp4 and /dev/null differ
diff --git a/art/gif_recyclerview.gif b/art/gif_recyclerview.gif
deleted file mode 100644
index 3f45ea4376a7fbf61d36d42534d7b3ee70d234de..0000000000000000000000000000000000000000
Binary files a/art/gif_recyclerview.gif and /dev/null differ
diff --git a/art/gif_recyclerview.mp4 b/art/gif_recyclerview.mp4
deleted file mode 100644
index 1b244e431cef7c5fb3a24ed32dd3ea93712ddcd3..0000000000000000000000000000000000000000
Binary files a/art/gif_recyclerview.mp4 and /dev/null differ
diff --git a/art/gif_recyclerview2.mp4 b/art/gif_recyclerview2.mp4
deleted file mode 100644
index 13ac50b7ca0be4e8f9d0ab7337a6ce638eb6db83..0000000000000000000000000000000000000000
Binary files a/art/gif_recyclerview2.mp4 and /dev/null differ
diff --git a/art/gif_scrollview.gif b/art/gif_scrollview.gif
deleted file mode 100644
index 70e32cc590fdbc5359dba69a71f36a1231894416..0000000000000000000000000000000000000000
Binary files a/art/gif_scrollview.gif and /dev/null differ
diff --git a/art/gif_scrollview.mp4 b/art/gif_scrollview.mp4
deleted file mode 100644
index 4db4f562f88dea4c8951b39455c993cbcfca9765..0000000000000000000000000000000000000000
Binary files a/art/gif_scrollview.mp4 and /dev/null differ
diff --git a/art/gif_webview.gif b/art/gif_webview.gif
deleted file mode 100644
index b5c037b55cb747a24c136b69978cd43ea9576dd4..0000000000000000000000000000000000000000
Binary files a/art/gif_webview.gif and /dev/null differ
diff --git a/art/gif_webview.mp4 b/art/gif_webview.mp4
deleted file mode 100644
index 55109d8995288dac59ef8e40cd669820497dac48..0000000000000000000000000000000000000000
Binary files a/art/gif_webview.mp4 and /dev/null differ
diff --git a/art/pic_large.png b/art/pic_large.png
deleted file mode 100644
index b20faa3318775e4886a2ef7f34da6da677470322..0000000000000000000000000000000000000000
Binary files a/art/pic_large.png and /dev/null differ
diff --git a/art/structure_v1.0.png b/art/structure_v1.0.png
deleted file mode 100644
index 247413defdd1928ea743fc9880630ec4486ac4f9..0000000000000000000000000000000000000000
Binary files a/art/structure_v1.0.png and /dev/null differ
diff --git a/art/wepay.png b/art/wepay.png
deleted file mode 100644
index 44b466dfa42cdf3dd1d6f950268ec9c93c03baf4..0000000000000000000000000000000000000000
Binary files a/art/wepay.png and /dev/null differ
diff --git a/build.gradle b/build.gradle
index 764eec0b873666b766b2a593c29ed5e45e383c2b..a4bbee50c84428507c792bf978676f0ff6fe17a8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,27 +1,40 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 6
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
buildscript {
repositories {
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.3.0'
- classpath 'com.novoda:bintray-release:0.3.4'
- // NOTE: Do not place your application dependencies here; they belong
- // in the individual module build.gradle files
+ classpath 'com.huawei.ohos:hap:2.4.5.0'
+ classpath 'com.huawei.ohos:decctest:1.2.4.1'
}
}
allprojects {
repositories {
+ maven {
+ url 'https://s01.oss.sonatype.org/content/repositories/snapshots/'
+ }
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
jcenter()
}
- tasks.withType(Javadoc) {
- options.addStringOption('Xdoclint:none', '-quiet')
- options.addStringOption('encoding', 'UTF-8')
- }
-}
-
-task clean(type: Delete) {
- delete rootProject.buildDir
}
diff --git a/app/.gitignore b/entry/.gitignore
similarity index 100%
rename from app/.gitignore
rename to entry/.gitignore
diff --git a/entry/build.gradle b/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..213915936f3928bc255857e56813754486e88a43
--- /dev/null
+++ b/entry/build.gradle
@@ -0,0 +1,27 @@
+apply plugin: 'com.huawei.ohos.hap'
+apply plugin: 'com.huawei.ohos.decctest'
+ohos {
+ compileSdkVersion 6
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+ buildTypes {
+ release {
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
+ }
+ }
+
+}
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testImplementation 'junit:junit:4.13'
+ ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.100'
+// implementation project(":library")
+ implementation('com.gitee.chinasoft_ohos:TwinklingRefreshLayout_library:0.0.1-SNAPSHOT')
+}
+decc {
+ supportType = ['html', 'xml']
+}
diff --git a/entry/proguard-rules.pro b/entry/proguard-rules.pro
new file mode 100644
index 0000000000000000000000000000000000000000..f7666e47561d514b2a76d5a7dfbb43ede86da92a
--- /dev/null
+++ b/entry/proguard-rules.pro
@@ -0,0 +1 @@
+# config module specific ProGuard rules here.
\ No newline at end of file
diff --git a/entry/src/main/config.json b/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..75502c48cc68ff44cf2caca5f230c169595788a7
--- /dev/null
+++ b/entry/src/main/config.json
@@ -0,0 +1,204 @@
+{
+ "app": {
+ "bundleName": "com.lcodecore.twinklingrefreshlayout",
+ "vendor": "lcodecore",
+ "version": {
+ "code": 1000000,
+ "name": "1.0.0"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.lcodecore.twinklingrefreshlayout",
+ "name": ".MyApplication",
+ "mainAbility": "com.lcodecore.twinklingrefreshlayout.MainAbility",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry",
+ "installationFree": false
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.lcodecore.twinklingrefreshlayout.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:entry_MainAbility",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.lcodecore.twinklingrefreshlayout.MusicAbility",
+ "icon": "$media:icon",
+ "description": "$string:musiclistviewfixedheaderability_description",
+ "label": "$string:entry_MusicListViewFixedHeaderAbility",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.lcodecore.twinklingrefreshlayout.FoodAbility",
+ "icon": "$media:icon",
+ "description": "$string:foodability_description",
+ "label": "$string:entry_FoodAbility",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.lcodecore.twinklingrefreshlayout.NormalViewAbility",
+ "icon": "$media:icon",
+ "description": "$string:normalviewability_description",
+ "label": "$string:entry_NormalViewAbility",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.lcodecore.twinklingrefreshlayout.ScienceAbility",
+ "icon": "$media:icon",
+ "description": "$string:scienceability_description",
+ "label": "$string:entry_ScienceAbility",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.lcodecore.twinklingrefreshlayout.StoryAbility",
+ "icon": "$media:icon",
+ "description": "$string:storyability_description",
+ "label": "$string:entry_StoryAbility",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.lcodecore.twinklingrefreshlayout.WebAbility",
+ "icon": "$media:icon",
+ "description": "$string:webability_description",
+ "label": "$string:entry_WebAbility",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.lcodecore.twinklingrefreshlayout.TestAbility",
+ "icon": "$media:icon",
+ "description": "$string:testability_description",
+ "label": "$string:entry_TestAbility",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.lcodecore.twinklingrefreshlayout.CoordinateAbility",
+ "icon": "$media:icon",
+ "description": "$string:coordinateability_description",
+ "label": "$string:entry_CoordinateAbility",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.lcodecore.twinklingrefreshlayout.PhotoAbility",
+ "icon": "$media:icon",
+ "description": "$string:photoability_description",
+ "label": "$string:entry_PhotoAbility",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ],
+ "metaData": {
+ "customizeData": [
+ {
+ "name": "hwc-theme",
+ "value": "androidhwext:style/Theme.Emui.NoTitleBar",
+ "extra": ""
+ }
+ ]
+ },
+ "reqPermissions": [
+ {
+ "reason": "Internet",
+ "name": "ohos.permission.INTERNET"
+ },
+ {
+ "reason": "GET_BUNDLE_INFO",
+ "name": "ohos.permission.GET_BUNDLE_INFO"
+ },
+ {
+ "reason": "Internet",
+ "name": "ohos.permission.ACCESS_BIOMETRIC_INTERNAL"
+ },
+ {
+ "name": "ohos.permission.READ_USER_STORAGE",
+ "reason": "Read User Storage",
+ "usedScene": {
+ "ability": [
+ "com.donkingliang.imageselector.MainAbility"
+ ],
+ "when": "inuse"
+ }
+ },
+ {
+ "name": "ohos.permission.READ_MEDIA",
+ "reason": "Get Camera",
+ "usedScene": {
+ "ability": [
+ "com.donkingliang.imageselector.MainAbility"
+ ],
+ "when": "inuse"
+ }
+ },
+ {
+ "name": "ohos.permission.MEDIA_LOCATION",
+ "reason": "Get Media",
+ "usedScene": {
+ "ability": [
+ "com.donkingliang.imageselector.MainAbility"
+ ],
+ "when": "inuse"
+ }
+ },
+ {
+ "name": "ohos.permission.WRITE_USER_STORAGE",
+ "reason": "get WRITE_USER_STORAGE",
+ "usedScene": {
+ "ability": [
+ "com.donkingliang.imageselector.MainAbility"
+ ],
+ "when": "inuse"
+ }
+ },
+ {
+ "name": "ohos.permission.MICROPHONE",
+ "reason": "get MICROPHONE",
+ "usedScene": {
+ "ability": [
+ "com.donkingliang.imageselector.MainAbility"
+ ],
+ "when": "inuse"
+ }
+ },
+ {
+ "name": "com.android.alarm.permission.SET_ALARM",
+ "reason": "get ALARM"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/CoordinateAbility.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/CoordinateAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..f92f7f8eb9bafb1cc4035580ad12aa86c13aa311
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/CoordinateAbility.java
@@ -0,0 +1,314 @@
+package com.lcodecore.twinklingrefreshlayout;
+
+import com.lcodecore.tkrefreshlayout.OnScrollListener;
+import com.lcodecore.tkrefreshlayout.XRecyclerView;
+import com.lcodecore.tkrefreshlayout.processor.loading.LoadingView;
+import com.lcodecore.tkrefreshlayout.utils.DeviceUtils;
+import com.lcodecore.twinklingrefreshlayout.adapter.PhotoAdapter;
+import com.lcodecore.twinklingrefreshlayout.beans.Photo;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.components.Component;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Text;
+import ohos.agp.window.service.Display;
+import ohos.agp.window.service.DisplayAttributes;
+import ohos.agp.window.service.DisplayManager;
+import ohos.app.dispatcher.TaskDispatcher;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+import ohos.multimodalinput.event.TouchEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import static ohos.multimodalinput.event.TouchEvent.POINT_MOVE;
+import static ohos.multimodalinput.event.TouchEvent.PRIMARY_POINT_DOWN;
+import static ohos.multimodalinput.event.TouchEvent.PRIMARY_POINT_UP;
+
+public class CoordinateAbility extends Ability implements Component.TouchEventListener, OnScrollListener {
+ private List photos = new ArrayList<>();
+ private XRecyclerView mRecyclerView;
+ private PhotoAdapter photoAdapter;
+ private LoadingView loadingView;
+ private DirectionalLayout loading_view;
+ private DirectionalLayout normal_view;
+ private int widthPm;
+ private int scrolltop = 1;
+ private Component root;
+ private Text loading_more;
+ private DirectionalLayout direc_layout;
+ /**
+ * listContainer是否滑到顶部
+ */
+ private boolean isTop = true;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_coordinate);
+ Optional
+ display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());
+ DisplayAttributes displayAttributes = display.get().getAttributes();
+ widthPm = displayAttributes.width;
+
+ root = findComponentById(ResourceTable.Id_root);
+ root.setTouchEventListener(this::onTouchEvent);
+ normal_view = (DirectionalLayout) findComponentById(ResourceTable.Id_normal_view);
+ loading_view = (DirectionalLayout) findComponentById(ResourceTable.Id_loading_view);
+ loadingView = (LoadingView) findComponentById(ResourceTable.Id_progress_loading);
+ loadingView.setBindStateChangedListener(loadingView);
+ loadingView.setPaintcolor(1);
+ loadingView.setSize(45);
+ loadingView.stopAnimation();
+ // 默认进度条的位置
+ loading_view.setScaleX(0.2f);
+ loading_view.setScaleY(0.2f);
+ loading_view.setPosition(widthPm / 2 - 50, -100);
+
+ loading_more = (Text) findComponentById(ResourceTable.Id_loading_more);
+ direc_layout = (DirectionalLayout) findComponentById(ResourceTable.Id_direc_layout);
+ mRecyclerView = (XRecyclerView) findComponentById(ResourceTable.Id_xRecyclerView);
+ mRecyclerView.setPullRefreshEnabled(true);
+ mRecyclerView.setLoadingMoreEnabled(true);
+ mRecyclerView.setSListener(this); // 设置回调
+ mRecyclerView.setTouchEventListener(this);
+
+ refreshCard();
+ photoAdapter = new PhotoAdapter(this, photos, ResourceTable.Layout_item_photo);
+ photoAdapter.setOnItemClickListener(new XRecyclerView.RecyclerAdapter.OnItemClickListener() {
+ @Override
+ public void onItemClick(Component component, int position) {
+ DeviceUtils.showToast(CoordinateAbility.this,"点击了List第" + position + "个");
+ }
+ });
+ mRecyclerView.setItemProvider(photoAdapter);
+ photoAdapter.setNumColumns(2);
+ mRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {
+ @Override
+ public void onRefresh() {
+ TaskDispatcher globalTaskDispatcher = getUITaskDispatcher();
+ globalTaskDispatcher.delayDispatch(() -> {
+ photos.clear();
+ refreshCard();
+ photoAdapter.notifyDataChanged();
+ if (mRecyclerView != null) {
+ mRecyclerView.refreshComplete();
+ }
+ }, 2000);
+ }
+
+ @Override
+ public void onLoadMore() {
+ mRecyclerView.setPosition(photos.size() + 1, photos.size() + 1);
+ loading_more.setVisibility(Component.HIDE);
+
+ TaskDispatcher globalTaskDispatcher = getUITaskDispatcher();
+ globalTaskDispatcher.delayDispatch(() -> {
+ loadMoreCard();
+ direc_layout.invalidate();
+ mRecyclerView.loadMoreComplete();
+ loading_more.setVisibility(Component.HIDE);
+ photoAdapter.notifyDataChanged();
+ }, 2000);
+ }
+ });
+
+ mRecyclerView.addScrolledListener(new Component.ScrolledListener() {
+ @Override
+ public void onContentScrolled(Component component, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
+ isTop = scrollY == 0;
+ }
+ });
+ }
+
+ public void refreshCard() {
+ photos.add(new Photo("", ResourceTable.Media_icon));
+ photos.add(new Photo("chest nut", ResourceTable.Media_photo1));
+ photos.add(new Photo("fish", ResourceTable.Media_photo2));
+ photos.add(new Photo("cat", ResourceTable.Media_photo10));
+ photos.add(new Photo("guitar", ResourceTable.Media_photo3));
+ photos.add(new Photo("common-hazel", ResourceTable.Media_photo4));
+ photos.add(new Photo("cherry", ResourceTable.Media_photo5));
+ photos.add(new Photo("flower details", ResourceTable.Media_photo6));
+ photos.add(new Photo("tree", ResourceTable.Media_photo7));
+ photos.add(new Photo("blue berries", ResourceTable.Media_photo8));
+ photos.add(new Photo("snow man", ResourceTable.Media_photo9));
+ }
+
+ public void loadMoreCard() {
+ photos.add(new Photo("chest nut", ResourceTable.Media_photo1));
+ photos.add(new Photo("fish", ResourceTable.Media_photo2));
+ photos.add(new Photo("cat", ResourceTable.Media_photo10));
+ photos.add(new Photo("guitar", ResourceTable.Media_photo3));
+ photos.add(new Photo("common-hazel", ResourceTable.Media_photo4));
+ photos.add(new Photo("cherry", ResourceTable.Media_photo5));
+ photos.add(new Photo("flower details", ResourceTable.Media_photo6));
+ photos.add(new Photo("tree", ResourceTable.Media_photo7));
+ photos.add(new Photo("blue berries", ResourceTable.Media_photo8));
+ photos.add(new Photo("snow man", ResourceTable.Media_photo9));
+ }
+
+
+ private float downY;
+ private float moveY;
+ private float mOffsetY;
+
+ @Override
+ public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
+ switch (touchEvent.getAction()) {
+ case PRIMARY_POINT_DOWN:
+ if (isTop && timeRecord()) {
+ downY = touchEvent.getPointerScreenPosition(0).getY();
+ }
+ return true;
+ case POINT_MOVE:
+ if (scrolltop == 1) {
+ if (timeRecord()) {
+ moveY = touchEvent.getPointerScreenPosition(touchEvent.getIndex()).getY();
+ mOffsetY = Math.min((moveY - downY), 700);
+ System.out.println("===========mOffsetY============="+moveY +"---"+downY);
+ if (mOffsetY > 10 && isTop && (moveY - downY) < 700) {
+ if ((moveY - downY) <= 400) {
+ float scaleSize = mOffsetY / 500.0f;
+ System.out.println("scaleSize======" + scaleSize);
+ if(scaleSize > 0.1f) {
+ loading_view.setScaleX(scaleSize);
+ loading_view.setScaleY(scaleSize);
+ } else {
+ loading_view.setScaleX(0.2f);
+ loading_view.setScaleY(0.2f);
+ }
+ } else {
+ loading_view.setScaleX(0.85f);
+ loading_view.setScaleY(0.85f);
+ }
+
+ mOffsetY = (moveY - downY);
+ loading_view.setPosition(widthPm / 2 - 50, (int) mOffsetY -50);
+ root.invalidate();
+ }
+ }
+ }
+ return true;
+ case PRIMARY_POINT_UP:
+ if (scrolltop == 1) {
+ if (timeRecord()) {
+ mOffsetY = Math.min((moveY - downY), 700);
+ if (mOffsetY < 400) {
+ AnimatorProperty animatorProperty = loading_view.createAnimatorProperty();
+ animatorProperty.setDuration(500).setDelay(100).scaleX(0).scaleY(0);
+ animatorProperty.start();
+
+ AnimatorProperty animatorProperty2 = loading_view.createAnimatorProperty();
+ animatorProperty2.moveFromY(mOffsetY).moveToY(-50).setDuration(500).setDelay(100);
+ animatorProperty2.start();
+
+ } else {
+ moveY = touchEvent.getPointerScreenPosition(touchEvent.getIndex()).getY();
+ loadingView.startAnimation();
+ animationFromTo(); //回退位置
+ // 设置 开始动画时间戳
+ lastClickTime = System.currentTimeMillis();
+ new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
+ @Override
+ public void run() {
+ loadingView.stopAnimation();
+ setTopHide();
+ lastClickTime = 0;
+ }
+ }, 2000);
+ root.invalidate();
+ mOffsetY = 0;
+ }
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+
+ public void setTopHide() {
+ AnimatorProperty animatorProperty = loading_view.createAnimatorProperty();
+ animatorProperty.setDuration(500).setDelay(10).scaleX(0).scaleY(0);
+ animatorProperty.start();
+ new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
+ @Override
+ public void run() {
+ animatorProperty.stop();
+ loading_view.setPosition(widthPm / 2 - 50, -50);
+ // 数据刷新
+ photos.clear();
+ refreshCard();
+ photoAdapter.notifyDataChanged();
+ }
+ }, 500);
+ }
+
+ @Override
+ public void onListener(int type) {
+ new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
+ @Override
+ public void run() {
+ float alpha = normal_view.getAlpha();
+ if (type == 1) {
+ scrolltop = 0;
+ if (alpha == 0) {
+ animationAlphaFromTo();
+ }
+ } else if (type == 0) {
+ scrolltop = 1;
+ if (alpha == 1) {
+ normal_view.setAlpha(0);
+ }
+ }
+ }
+ }, 100);
+
+ }
+
+ private AnimatorValue animatorValue;
+ public void animationAlphaFromTo() {
+ if (null != animatorValue) {
+ animatorValue.stop();
+ }
+ animatorValue = new AnimatorValue();
+ animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ normal_view.setAlpha(v);
+ }
+ });
+ animatorValue.setDuration(200);
+ animatorValue.start();
+ }
+
+ private AnimatorProperty animatorProperty;
+
+ public void animationFromTo() {
+ animatorProperty = loading_view.createAnimatorProperty();
+ animatorProperty.moveFromY(mOffsetY).moveToY(200).setDuration(500).setDelay(100);
+ animatorProperty.start();
+ }
+
+ // 两次点击按钮之间的点击间隔不能少于1000毫秒
+ private final int MIN_CLICK_DELAY_TIME = 2000;
+ private long lastClickTime = 0;
+
+ public boolean timeRecord() {
+ if (lastClickTime == 0) {
+ return true;
+ }
+ long curClickTime = System.currentTimeMillis();
+ if ((curClickTime - lastClickTime) >= MIN_CLICK_DELAY_TIME) {
+ // 超过点击间隔后再将lastClickTime重置为当前点击时间
+ lastClickTime = curClickTime;
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/FoodAbility.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/FoodAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..10918cadbb3111b2b2f03066e9c93a14811b94d9
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/FoodAbility.java
@@ -0,0 +1,134 @@
+package com.lcodecore.twinklingrefreshlayout;
+
+import com.lcodecore.tkrefreshlayout.utils.DeviceUtils;
+import com.lcodecore.twinklingrefreshlayout.beans.Food;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.colors.RgbColor;
+import ohos.agp.components.BaseItemProvider;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.ListContainer;
+import ohos.agp.components.Text;
+import ohos.agp.components.element.ShapeElement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FoodAbility extends Ability {
+ private List foods = new ArrayList<>();
+ private ListAdapter mAdapter;
+ private ListContainer mRecyclerView;
+ private Image bt_back;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_food);
+
+ bt_back = (Image) findComponentById(ResourceTable.Id_bt_back);
+ bt_back.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ terminateAbility();
+ }
+ });
+
+ mRecyclerView = (ListContainer) findComponentById(ResourceTable.Id_xRecyclerView);
+
+ refreshCard();
+ mAdapter = new ListAdapter(this, foods);
+ mRecyclerView.setItemProvider(mAdapter);
+
+ mRecyclerView.setItemClickedListener(new ListContainer.ItemClickedListener() {
+ @Override
+ public void onItemClicked(ListContainer listContainer, Component component, int arg2, long l) {
+ DeviceUtils.showToast(FoodAbility.this,"点击了List第" + arg2 + "个");
+ }
+ });
+ mRecyclerView.setLongClickable(false);
+ mRecyclerView.setReboundEffect(true);
+ }
+
+ void refreshCard() {
+ foods.add(new Food("Preparing Salmon Steak Close Up", "BY VIKTOR HANACEK", ResourceTable.Media_food1, ResourceTable.Media_avatar0));
+ foods.add(new Food("Fresh & Healthy Fitness Broccoli Pie with Basil", "BY VIKTOR HANACEK", ResourceTable.Media_food2, ResourceTable.Media_avatar1));
+ foods.add(new Food("Enjoying a Tasty Burger", "BY VIKTOR HANACEK", ResourceTable.Media_food3, ResourceTable.Media_avatar2));
+ foods.add(new Food("Fresh Strawberries and Blackberries in Little Bowl", "BY VIKTOR HANACEK", ResourceTable.Media_food4, ResourceTable.Media_avatar3));
+ foods.add(new Food("Baked Healthy Fitness Broccoli Pie with Basil", "BY VIKTOR HANACEK", ResourceTable.Media_food5, ResourceTable.Media_avatar4));
+ }
+
+ public class ListAdapter extends BaseItemProvider {
+
+ private final Ability mActivity;
+ private final LayoutScatter mInflater;
+ private final List items;
+
+ public ListAdapter(Ability ability, List foods) {
+ mActivity = ability;
+ this.items = foods;
+ mInflater = LayoutScatter.getInstance(ability);
+ }
+
+ @Override
+ public int getCount() {
+ return items == null ? 0 : items.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ if (items != null && position >= 0 && position < items.size()) {
+ return items.get(position);
+ }
+ return null;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public Component getComponent(int position, Component component, ComponentContainer componentContainer) {
+ Food foots = (Food) getItem(position);
+ ViewHolder holder;
+ if (component == null) {
+ component = mInflater.parse(ResourceTable.Layout_item_food, componentContainer, false);
+ holder = new ViewHolder(component);
+ } else {
+ holder = (ViewHolder) component.getTag();
+ }
+
+ ShapeElement element = new ShapeElement();
+ element.setRgbColor(RgbColor.fromArgbInt(0xffffffff));
+ element.setCornerRadius(10);
+ holder.derection_bg.setBackground(element);
+ holder.tv_food.setText(foots.title);
+ holder.tv_info.setText(foots.info);
+ holder.avatar.setPixelMap(foots.avatar_id);
+ holder.iv_food.setPixelMap(foots.imageSrc);
+
+ return component;
+ }
+
+ private class ViewHolder {
+ DirectionalLayout derection_bg;
+ Text tv_food;
+ Text tv_info;
+ Image avatar;
+ Image iv_food;
+
+ public ViewHolder(Component view) {
+ derection_bg = (DirectionalLayout) view.findComponentById(ResourceTable.Id_derection_bg);
+ tv_food = (Text) view.findComponentById(ResourceTable.Id_tv_food);
+ tv_info = (Text) view.findComponentById(ResourceTable.Id_tv_info);
+ avatar = (Image) view.findComponentById(ResourceTable.Id_avatar);
+ iv_food = (Image) view.findComponentById(ResourceTable.Id_iv_food);
+ view.setTag(this);
+ }
+ }
+ }
+}
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/MainAbility.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..f2a471defebb93aab9449dc119c1af607cf92dcd
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/MainAbility.java
@@ -0,0 +1,71 @@
+package com.lcodecore.twinklingrefreshlayout;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.aafwk.content.Operation;
+import ohos.agp.components.Component;
+
+public class MainAbility extends Ability implements Component.ClickedListener {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ findComponentById(ResourceTable.Id_bt_music).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_food).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_science).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_photo).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_story).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_enjoy).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_coordinate).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_normalView).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_test).setClickedListener(this);
+ }
+
+ @Override
+ public void onClick(Component component) {
+ switch (component.getId()) {
+ case ResourceTable.Id_bt_music:
+ jumpPage(MusicAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_food:
+ jumpPage(FoodAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_science:
+ jumpPage(ScienceAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_photo:
+ jumpPage(PhotoAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_story:
+ jumpPage(StoryAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_enjoy:
+ jumpPage(WebAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_coordinate:
+ jumpPage(CoordinateAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_normalView:
+ jumpPage(NormalViewAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_test:
+ jumpPage(TestAbility.class.getName());
+ break;
+ }
+ }
+
+ /**
+ * 页面跳转
+ *
+ * @param abilityName abilityName
+ */
+ public void jumpPage(String abilityName){
+ Intent intent = new Intent();
+ Operation operation = new Intent.OperationBuilder()
+ .withBundleName(getBundleName())
+ .withAbilityName(abilityName)
+ .build();
+ intent.setOperation(operation);
+ startAbility(intent);
+ }
+}
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/MusicAbility.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/MusicAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..b7ca7e676d189c756bdeceeeb0fe5cac5fb43cc6
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/MusicAbility.java
@@ -0,0 +1,119 @@
+package com.lcodecore.twinklingrefreshlayout;
+
+import com.lcodecore.tkrefreshlayout.OnViewListener;
+import com.lcodecore.tkrefreshlayout.XRecyclerView;
+import com.lcodecore.tkrefreshlayout.utils.DeviceUtils;
+import com.lcodecore.twinklingrefreshlayout.adapter.MusicAdapter;
+import com.lcodecore.twinklingrefreshlayout.beans.Card;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.Text;
+import ohos.app.dispatcher.TaskDispatcher;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MusicAbility extends Ability implements OnViewListener {
+ private List cards = new ArrayList<>();
+ private MusicAdapter mAdapter;
+ private XRecyclerView mRecyclerView;
+ private DirectionalLayout direc_layout;
+ private Text loading_more;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_music);
+ Image back = (Image) findComponentById(ResourceTable.Id_back);
+ back.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ terminateAbility();
+ }
+ });
+ direc_layout = (DirectionalLayout) findComponentById(ResourceTable.Id_direc_layout);
+ loading_more = (Text) findComponentById(ResourceTable.Id_loading_more);
+ mRecyclerView = (XRecyclerView) findComponentById(ResourceTable.Id_xRecyclerView);
+ mRecyclerView.setViewListener(this);
+ mRecyclerView.setPullRefreshEnabled(true);
+ mRecyclerView.setLoadingMoreEnabled(true);
+ mRecyclerView.setLongClickable(false);
+
+ mRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {
+ @Override
+ public void onRefresh() {
+ TaskDispatcher globalTaskDispatcher = getUITaskDispatcher();
+ globalTaskDispatcher.delayDispatch(() -> {
+ cards.clear();
+ refreshCard();
+ mAdapter.notifyDataChanged();
+ if (mRecyclerView != null) {
+ mRecyclerView.refreshComplete();
+ }
+ }, 2000);
+ }
+
+ @Override
+ public void onLoadMore() {
+ loading_more.setVisibility(Component.VISIBLE);
+
+ TaskDispatcher globalTaskDispatcher = getUITaskDispatcher();
+ globalTaskDispatcher.delayDispatch(() -> {
+ loadMoreCard();
+ direc_layout.invalidate();
+ mRecyclerView.loadMoreComplete();
+ loading_more.setVisibility(Component.HIDE);
+ mAdapter.notifyDataChanged();
+ }, 2000);
+ }
+ });
+
+ refreshCard();
+ mAdapter = new MusicAdapter(this,cards,ResourceTable.Layout_item_music);
+ mRecyclerView.setItemProvider(mAdapter);
+ mAdapter.setNumColumns(1);
+ mAdapter.setOnItemClickListener(new XRecyclerView.RecyclerAdapter.OnItemClickListener() {
+ @Override
+ public void onItemClick(Component component, int position) {
+ DeviceUtils.showToast(MusicAbility.this,"点击了List第" + position + "个");
+ }
+ });
+ }
+
+ private Component initHeader() {
+ LayoutScatter scatter = LayoutScatter.getInstance(getContext());
+ Component header = scatter.parse(ResourceTable.Layout_header_music, null, false);
+ return header;
+ }
+
+ public void refreshCard(){
+ cards.add(new Card("", "", ResourceTable.Media_icon));
+ cards.add(new Card("What Do You Mean?", "Justin Bieber", ResourceTable.Media_avatar1));
+ cards.add(new Card("Secret Garden", "Song From A Secret Garden", ResourceTable.Media_avatar2));
+ cards.add(new Card("Moves Like Jagger","Maroon 5",ResourceTable.Media_avatar3));
+ cards.add(new Card("Work Hard, Play Hard","Wiz Khalifa",ResourceTable.Media_avatar4));
+ cards.add(new Card("See You Again","Charlie Puth",ResourceTable.Media_avatar7));
+ cards.add(new Card("Love The Way You Lie (Part Ii)","Rihanna",ResourceTable.Media_avatar5));
+ cards.add(new Card("Call Me Maybe","Carly Rae Jepsen",ResourceTable.Media_avatar9));
+ cards.add(new Card("Let It Go","Demi Lovato",ResourceTable.Media_avatar8));
+ cards.add(new Card("What Do You Mean?", "Justin Bieber", ResourceTable.Media_avatar1));
+ }
+
+ public void loadMoreCard(){
+ cards.add(new Card("You Raise Me Up","Westlife",ResourceTable.Media_avatar6));
+ cards.add(new Card("See You Again","Charlie Puth",ResourceTable.Media_avatar7));
+ cards.add(new Card("Love Story","Taylor Swift",ResourceTable.Media_avatar0));
+ cards.add(new Card("Let It Go","Demi Lovato",ResourceTable.Media_avatar8));
+ cards.add(new Card("Secret Garden", "Song From A Secret Garden", ResourceTable.Media_avatar2));
+ cards.add(new Card("Call Me Maybe","Carly Rae Jepsen",ResourceTable.Media_avatar9));
+ }
+
+ @Override
+ public void onViewListener() {
+ mAdapter.notifyDataChanged();
+ }
+}
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/MyApplication.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ca5b8f331095032412478e4f5d7ea00d0d5eb8d
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/MyApplication.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.twinklingrefreshlayout;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+/**
+ * MyApplication类
+ *
+ * @since 2021-07-19
+ */
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/NormalViewAbility.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/NormalViewAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..fdbf645c7b8c5fd569fa1ab2fd138fa94491813b
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/NormalViewAbility.java
@@ -0,0 +1,15 @@
+package com.lcodecore.twinklingrefreshlayout;
+
+import com.lcodecore.tkrefreshlayout.XRecyclerView;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class NormalViewAbility extends Ability {
+ private XRecyclerView mRecyclerView;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_normal_view);
+ }
+}
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/PhotoAbility.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/PhotoAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..a3a8af8acb824d4bf3ea169b95905ca6b4cafc67
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/PhotoAbility.java
@@ -0,0 +1,238 @@
+package com.lcodecore.twinklingrefreshlayout;
+
+import com.lcodecore.tkrefreshlayout.OnAnimEndListener;
+import com.lcodecore.tkrefreshlayout.OnRefreshListener;
+import com.lcodecore.tkrefreshlayout.OnScrollListener;
+import com.lcodecore.tkrefreshlayout.XRecyclerView;
+import com.lcodecore.tkrefreshlayout.header.bezierlayout.BezierLayout;
+import com.lcodecore.tkrefreshlayout.utils.DeviceUtils;
+import com.lcodecore.twinklingrefreshlayout.adapter.PhotoAnimationAdapter;
+import com.lcodecore.twinklingrefreshlayout.beans.Photo;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.Text;
+import ohos.agp.window.service.Display;
+import ohos.agp.window.service.DisplayAttributes;
+import ohos.agp.window.service.DisplayManager;
+import ohos.app.dispatcher.TaskDispatcher;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+import ohos.multimodalinput.event.TouchEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import static ohos.multimodalinput.event.TouchEvent.POINT_MOVE;
+import static ohos.multimodalinput.event.TouchEvent.PRIMARY_POINT_DOWN;
+import static ohos.multimodalinput.event.TouchEvent.PRIMARY_POINT_UP;
+
+public class PhotoAbility extends Ability implements Component.TouchEventListener, OnScrollListener, OnRefreshListener {
+ private List photos = new ArrayList<>();
+ private XRecyclerView mRecyclerView;
+ private PhotoAnimationAdapter photoAdapter;
+ private Text tv_spacing;
+ private Image bt_back;
+ private BezierLayout headerView;
+ private DirectionalLayout root;
+ private Text loading_more;
+ private DirectionalLayout direc_layout;
+ private int winW;
+ /**
+ * listContainer是否滑到顶部
+ */
+ private boolean isTop = true;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_photo);
+ Optional
+ display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());
+ DisplayAttributes displayAttributes = display.get().getAttributes();
+ winW = displayAttributes.width;
+ tv_spacing = (Text) findComponentById(ResourceTable.Id_tv_spacing);
+ bt_back = (Image) findComponentById(ResourceTable.Id_bt_back);
+ bt_back.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ terminateAbility();
+ }
+ });
+
+ direc_layout = (DirectionalLayout) findComponentById(ResourceTable.Id_direc_layout);
+ loading_more = (Text) findComponentById(ResourceTable.Id_loading_more);
+ root = (DirectionalLayout) findComponentById(ResourceTable.Id_root);
+ root.setTouchEventListener(this);
+ mRecyclerView = (XRecyclerView) findComponentById(ResourceTable.Id_xRecyclerView);
+ mRecyclerView.setPullRefreshEnabled(false);
+ mRecyclerView.setLoadingMoreEnabled(true);
+ mRecyclerView.setTouchEventListener(this);
+ headerView = (BezierLayout) findComponentById(ResourceTable.Id_bezierlayout);
+ headerView.setRefreshListener(this);
+ headerView.setHeight(0);
+ refreshCard();
+ photoAdapter = new PhotoAnimationAdapter(this, photos, ResourceTable.Layout_item_photoAnima);
+ photoAdapter.setOnItemClickListener(new XRecyclerView.RecyclerAdapter.OnItemClickListener() {
+ @Override
+ public void onItemClick(Component component, int position) {
+ DeviceUtils.showToast(PhotoAbility.this,"点击了List第" + position + "个");
+ }
+ });
+ mRecyclerView.setItemProvider(photoAdapter);
+ photoAdapter.setNumColumns(2);
+ mRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {
+ @Override
+ public void onRefresh() {
+ TaskDispatcher globalTaskDispatcher = getUITaskDispatcher();
+ globalTaskDispatcher.delayDispatch(() -> {
+ photos.clear();
+ refreshCard();
+ photoAdapter.notifyDataChanged();
+ if (mRecyclerView != null) {
+ mRecyclerView.refreshComplete();
+ }
+ }, 2000);
+ }
+
+ @Override
+ public void onLoadMore() {
+ mRecyclerView.setPosition(photos.size(), photos.size());
+ loading_more.setVisibility(Component.HIDE);
+
+ TaskDispatcher globalTaskDispatcher = getUITaskDispatcher();
+ globalTaskDispatcher.delayDispatch(() -> {
+ loadMoreCard();
+ direc_layout.invalidate();
+ mRecyclerView.loadMoreComplete();
+ loading_more.setVisibility(Component.HIDE);
+ photoAdapter.notifyDataChanged();
+ }, 2000);
+ }
+ });
+
+ mRecyclerView.addScrolledListener(new Component.ScrolledListener() {
+ @Override
+ public void onContentScrolled(Component component, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
+ isTop = scrollY == 0;
+ System.out.println("----------------------" + scrollY + " = isTop = " + isTop);
+ }
+ });
+ }
+
+ @Override
+ public void onListener(int type) {
+ }
+
+ private float downY;
+ private float moveY;
+ private float mOffsetY;
+
+ @Override
+ public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
+ switch (touchEvent.getAction()) {
+ case PRIMARY_POINT_DOWN:
+ if (isTop && timeRecord()) {
+ downY = touchEvent.getPointerScreenPosition(0).getY();
+ headerView.onPullingDown(1.75f, 400, downY);
+ }
+ return true;
+ case POINT_MOVE:
+ if (isTop && timeRecord()) {
+ moveY = touchEvent.getPointerScreenPosition(touchEvent.getIndex()).getY();
+ mOffsetY = Math.min((moveY - downY), 400);
+ if (mOffsetY > 10 && isTop) {
+ System.out.println("============" + (moveY - downY));
+ headerView.setHeight((int) mOffsetY);
+ headerView.onPullingDown(1.75f, 400, mOffsetY - 200);
+ }
+ }
+ return true;
+ case PRIMARY_POINT_UP:
+ if (isTop && timeRecord()) {
+ moveY = touchEvent.getPointerScreenPosition(touchEvent.getIndex()).getY();
+ mOffsetY = Math.min((moveY - downY), 400);
+ if (mOffsetY <= 300) {
+ headerView.releaseAnim(headerView, mOffsetY, 0);
+ } else {
+ headerView.onPullReleasing(1.75f, 400, mOffsetY);
+ headerView.startAnim(400, mOffsetY);
+ // 设置 开始动画时间戳
+ lastClickTime = System.currentTimeMillis();
+ new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
+ @Override
+ public void run() {
+ headerView.onFinish(new OnAnimEndListener() {
+ @Override
+ public void onAnimEnd() {
+ headerView.releaseAnim(headerView, mOffsetY, 0);
+ lastClickTime = 0;
+ }
+ });
+ }
+ }, 2000);
+ root.invalidate();
+ }
+ }
+ return false;
+ }
+ return false;
+ }
+
+
+ public void refreshCard() {
+ photos.add(new Photo("chest nut", ResourceTable.Media_photo1));
+ photos.add(new Photo("fish", ResourceTable.Media_photo2));
+ photos.add(new Photo("cat", ResourceTable.Media_photo10));
+ photos.add(new Photo("guitar", ResourceTable.Media_photo3));
+ photos.add(new Photo("common-hazel", ResourceTable.Media_photo4));
+ photos.add(new Photo("cherry", ResourceTable.Media_photo5));
+ photos.add(new Photo("flower details", ResourceTable.Media_photo6));
+ photos.add(new Photo("tree", ResourceTable.Media_photo7));
+ photos.add(new Photo("blue berries", ResourceTable.Media_photo8));
+ photos.add(new Photo("snow man", ResourceTable.Media_photo9));
+ photos.add(new Photo("cherry", ResourceTable.Media_photo5));
+ }
+
+ public void loadMoreCard() {
+ photos.add(new Photo("chest nut", ResourceTable.Media_photo1));
+ photos.add(new Photo("fish", ResourceTable.Media_photo2));
+ photos.add(new Photo("cat", ResourceTable.Media_photo10));
+ photos.add(new Photo("guitar", ResourceTable.Media_photo3));
+ photos.add(new Photo("common-hazel", ResourceTable.Media_photo4));
+ photos.add(new Photo("cherry", ResourceTable.Media_photo5));
+ photos.add(new Photo("flower details", ResourceTable.Media_photo6));
+ photos.add(new Photo("tree", ResourceTable.Media_photo7));
+ photos.add(new Photo("blue berries", ResourceTable.Media_photo8));
+ photos.add(new Photo("snow man", ResourceTable.Media_photo9));
+ }
+
+ // 两次点击按钮之间的点击间隔不能少于1000毫秒
+ private final int MIN_CLICK_DELAY_TIME = 2000;
+ private long lastClickTime = 0;
+
+ public boolean timeRecord() {
+ if (lastClickTime == 0) {
+ return true;
+ }
+ long curClickTime = System.currentTimeMillis();
+ if ((curClickTime - lastClickTime) >= MIN_CLICK_DELAY_TIME) {
+ // 超过点击间隔后再将lastClickTime重置为当前点击时间
+ lastClickTime = curClickTime;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onRefresh() {
+ // 数据刷新
+ photos.clear();
+ refreshCard();
+ photoAdapter.notifyDataChanged();
+ root.invalidate();
+ }
+}
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/ScienceAbility.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/ScienceAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..c84685ff491935fad36c71bae51989e90bd0e2b9
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/ScienceAbility.java
@@ -0,0 +1,117 @@
+package com.lcodecore.twinklingrefreshlayout;
+
+import com.lcodecore.tkrefreshlayout.XRecyclerView;
+import com.lcodecore.tkrefreshlayout.utils.DeviceUtils;
+import com.lcodecore.twinklingrefreshlayout.adapter.ScienceAdapter;
+import com.lcodecore.twinklingrefreshlayout.beans.Card;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.Text;
+import ohos.app.dispatcher.TaskDispatcher;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ScienceAbility extends Ability {
+ private List cards = new ArrayList<>();
+ private XRecyclerView mRecyclerView;
+ private ScienceAdapter scienceAdapter;
+ private Text tv_spacing;
+ private Image bt_back;
+ private Text loading_more;
+ private DirectionalLayout direc_layout;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_science);
+
+ tv_spacing = (Text) findComponentById(ResourceTable.Id_tv_spacing);
+ tv_spacing.setText("S C I E N C E");
+ bt_back = (Image) findComponentById(ResourceTable.Id_bt_back);
+ bt_back.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ terminateAbility();
+ }
+ });
+
+ loading_more = (Text) findComponentById(ResourceTable.Id_loading_more);
+ direc_layout = (DirectionalLayout) findComponentById(ResourceTable.Id_direc_layout);
+ mRecyclerView = (XRecyclerView) findComponentById(ResourceTable.Id_xRecyclerView);
+ mRecyclerView.setLoadingMoreEnabled(true);
+ mRecyclerView.setLoadingMoreEnabled(true);
+ mRecyclerView.setHeadFootStyle(3);
+
+ refreshCard();
+ scienceAdapter = new ScienceAdapter(this,cards,ResourceTable.Layout_item_science);
+ scienceAdapter.setOnItemClickListener(new XRecyclerView.RecyclerAdapter.OnItemClickListener() {
+ @Override
+ public void onItemClick(Component component, int position) {
+ DeviceUtils.showToast(ScienceAbility.this,"点击了List第" + position + "个");
+ }
+ });
+ mRecyclerView.setItemProvider(scienceAdapter);
+ scienceAdapter.setNumColumns(2);
+ mRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {
+ @Override
+ public void onRefresh() {
+ TaskDispatcher globalTaskDispatcher = getUITaskDispatcher();
+ globalTaskDispatcher.delayDispatch(() -> {
+ cards.clear();
+ refreshCard();
+ scienceAdapter.notifyDataChanged();
+ if (mRecyclerView != null) {
+ mRecyclerView.refreshComplete();
+ }
+ }, 2000);
+ }
+
+ @Override
+ public void onLoadMore() {
+ mRecyclerView.setPosition(cards.size(),cards.size());
+ loading_more.setVisibility(Component.VISIBLE);
+
+ TaskDispatcher globalTaskDispatcher = getUITaskDispatcher();
+ globalTaskDispatcher.delayDispatch(() -> {
+ loadMoreCard();
+ direc_layout.invalidate();
+ mRecyclerView.loadMoreComplete();
+ loading_more.setVisibility(Component.HIDE);
+ scienceAdapter.notifyDataChanged();
+ }, 2000);
+ }
+ });
+ }
+
+ public void refreshCard() {
+ cards.add(new Card("genetics", "", ResourceTable.Media_science1));
+ cards.add(new Card("globe", "", ResourceTable.Media_science2));
+ cards.add(new Card("lab-flask-leaf", "", ResourceTable.Media_science3));
+ cards.add(new Card("magnet", "", ResourceTable.Media_science4));
+ cards.add(new Card("microscope", "", ResourceTable.Media_science5));
+ cards.add(new Card("moon", "", ResourceTable.Media_science6));
+ cards.add(new Card("telescope", "", ResourceTable.Media_science7));
+ cards.add(new Card("satellite", "", ResourceTable.Media_science8));
+ cards.add(new Card("Newtons-cradle", "", ResourceTable.Media_science9));
+ cards.add(new Card("nuclear-symbol", "", ResourceTable.Media_science10));
+ cards.add(new Card("genetics2", "", ResourceTable.Media_science1));
+ cards.add(new Card("globe2", "", ResourceTable.Media_science2));
+ }
+
+ public void loadMoreCard() {
+ cards.add(new Card("genetics", "", ResourceTable.Media_science1));
+ cards.add(new Card("globe", "", ResourceTable.Media_science2));
+ cards.add(new Card("lab-flask-leaf", "", ResourceTable.Media_science3));
+ cards.add(new Card("magnet", "", ResourceTable.Media_science4));
+ cards.add(new Card("microscope", "", ResourceTable.Media_science5));
+ cards.add(new Card("moon", "", ResourceTable.Media_science6));
+ cards.add(new Card("telescope", "", ResourceTable.Media_science7));
+ cards.add(new Card("satellite", "", ResourceTable.Media_science8));
+ cards.add(new Card("Newtons-cradle", "", ResourceTable.Media_science9));
+ cards.add(new Card("nuclear-symbol", "", ResourceTable.Media_science10));
+ }
+}
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/StoryAbility.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/StoryAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..290bd6d9ff676654addc23e852d78c258000dd4f
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/StoryAbility.java
@@ -0,0 +1,131 @@
+package com.lcodecore.twinklingrefreshlayout;
+
+import com.lcodecore.tkrefreshlayout.ProgressStyle;
+import com.lcodecore.tkrefreshlayout.XRecyclerView;
+import com.lcodecore.tkrefreshlayout.utils.DeviceUtils;
+import com.lcodecore.twinklingrefreshlayout.beans.Card;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.LayoutScatter;
+import ohos.app.Context;
+import ohos.app.dispatcher.TaskDispatcher;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class StoryAbility extends Ability {
+ private List cards = new ArrayList<>();
+ private XRecyclerView mRecyclerView;
+ private MyAdapter mAdapter;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_story);
+
+ mRecyclerView = (XRecyclerView) findComponentById(ResourceTable.Id_xRecyclerView);
+ mRecyclerView.setLoadingMoreProgressStyle(ProgressStyle.BallClipRotate);
+ mRecyclerView.setLoadingMoreEnabled(true);
+ mRecyclerView.setLoadingMoreEnabled(true);
+
+ refreshCard();
+ ArrayList listData = new ArrayList<>();
+ for (int num = 0; num < 1; num++) {
+ listData.add("数据" + num);
+ }
+ mAdapter = new MyAdapter<>(getContext(), listData, ResourceTable.Layout_item_story);
+ mRecyclerView.setItemProvider(mAdapter);
+ mAdapter.setOnItemClickListener(new XRecyclerView.RecyclerAdapter.OnItemClickListener() {
+ @Override
+ public void onItemClick(Component component, int position) {
+ DeviceUtils.showToast(StoryAbility.this,"点击了List第" + position + "个");
+ }
+ });
+
+ mRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {
+ @Override
+ public void onRefresh() {
+ TaskDispatcher globalTaskDispatcher = getUITaskDispatcher();
+ globalTaskDispatcher.delayDispatch(() -> {
+ cards.clear();
+ mAdapter.notifyDataChanged();
+ if (mRecyclerView != null) {
+ mRecyclerView.refreshComplete();
+ }
+ }, 2000);
+ }
+
+ @Override
+ public void onLoadMore() {
+ TaskDispatcher globalTaskDispatcher = getUITaskDispatcher();
+ globalTaskDispatcher.delayDispatch(() -> {
+ mRecyclerView.loadMoreComplete();
+ mAdapter.notifyDataChanged();
+ }, 2000);
+ }
+ });
+ }
+
+ private Component initHeader() {
+ LayoutScatter scatter = LayoutScatter.getInstance(getContext());
+ Component header = scatter.parse(ResourceTable.Layout_item_story, null, false);
+ return header;
+ }
+
+ public void refreshCard(){
+ }
+
+ public static class MyAdapter extends XRecyclerView.RecyclerAdapter {
+ /**
+ * Adapter构造方法
+ *
+ * @param context 上下文
+ * @param data 列表数据
+ * @param layoutId 组件ID
+ */
+ public MyAdapter(Context context, List data, int layoutId) {
+ super(context, data, layoutId);
+ }
+
+ @Override
+ public List getData() {
+ return super.getData();
+ }
+
+ @Override
+ public int getCount() {
+ return super.getCount();
+ }
+
+ @Override
+ public T getItem(int position) {
+ return super.getItem(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return super.getItemId(position);
+ }
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer parent) {
+ return super.getComponent(position, convertComponent, parent);
+ }
+
+ @Override
+ public void setNumColumns(int numColumns) {
+ super.setNumColumns(numColumns);
+ }
+
+ @Override
+ public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
+ super.setOnItemClickListener(onItemClickListener);
+ }
+
+ @Override
+ public void bind(ViewHolder holder, T s, int position) {
+ }
+ }
+}
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/TestAbility.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/TestAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..63ea3e5a4881a735b2bb3f00a30da8ee235349b9
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/TestAbility.java
@@ -0,0 +1,393 @@
+package com.lcodecore.twinklingrefreshlayout;
+
+import com.lcodecore.tkrefreshlayout.OnScrollListener;
+import com.lcodecore.tkrefreshlayout.XRecyclerView;
+import com.lcodecore.tkrefreshlayout.utils.DeviceUtils;
+import com.lcodecore.twinklingrefreshlayout.adapter.ScienceAdapter;
+import com.lcodecore.twinklingrefreshlayout.beans.Card;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.Text;
+import ohos.agp.components.element.FrameAnimationElement;
+import ohos.agp.window.service.Display;
+import ohos.agp.window.service.DisplayAttributes;
+import ohos.agp.window.service.DisplayManager;
+import ohos.app.dispatcher.TaskDispatcher;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+import ohos.multimodalinput.event.TouchEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import static ohos.agp.components.Component.HIDE;
+import static ohos.agp.components.Component.VISIBLE;
+import static ohos.multimodalinput.event.TouchEvent.POINT_MOVE;
+import static ohos.multimodalinput.event.TouchEvent.PRIMARY_POINT_DOWN;
+import static ohos.multimodalinput.event.TouchEvent.PRIMARY_POINT_UP;
+
+public class TestAbility extends Ability implements Component.ClickedListener, Component.TouchEventListener, OnScrollListener {
+ private List cards = new ArrayList<>();
+ private XRecyclerView mRecyclerView;
+ private ScienceAdapter scienceAdapter;
+ private Text tv_spacing;
+ private Image bt_back;
+ private Text loading_more;
+ private Text mStatusTextView;
+ private DirectionalLayout direc_layout;
+
+ private DirectionalLayout loading_view;
+ private DirectionalLayout listview_header_text;
+ private DirectionalLayout top_root;
+ private DirectionalLayout componentContainer;
+ private FrameAnimationElement frameAnimationElement;
+ private Component component2;
+
+ private TestButton toggle_enableLoadmore, toggle_pureScrollMode_on, toggle_overScrollTopShow, toggle_osFooterShow, toggle_enableOverScroll, toggle_enableKeepIView,
+ toggle_showRefreshingWhenOverScroll, toggle_showLoadingWhenOverScroll, toggle_floatRefresh, toggle_autoLoadMore,toggle_enableRefresh;
+ /**
+ * listContainer是否滑到顶部
+ */
+ private boolean isTop = true;
+ private Component root;
+ private int widthPm;
+ private int scrolltop = 1;
+
+ private Image mArrowImageView;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_test);
+ Optional
+ display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());
+ DisplayAttributes displayAttributes = display.get().getAttributes();
+ widthPm = displayAttributes.width;
+
+ tv_spacing = (Text) findComponentById(ResourceTable.Id_tv_spacing);
+ tv_spacing.setText("S C I E N C E");
+ bt_back = (Image) findComponentById(ResourceTable.Id_bt_back);
+ bt_back.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ terminateAbility();
+ }
+ });
+
+ toggle_enableLoadmore = new TestButton(ResourceTable.Id_toggle_enableLoadmore, "enableLoadmore", true);
+ toggle_pureScrollMode_on = new TestButton(ResourceTable.Id_toggle_pureScrollMode_on, "pureScrollMode_on", false);
+ toggle_overScrollTopShow = new TestButton(ResourceTable.Id_toggle_overScrollTopShow, "overScrollTopShow", true);
+ toggle_osFooterShow = new TestButton(ResourceTable.Id_toggle_osFooterShow, "osFooterShow", true);
+ toggle_enableOverScroll = new TestButton(ResourceTable.Id_toggle_enableOverScroll, "enableOverScroll", true);
+ toggle_enableKeepIView = new TestButton(ResourceTable.Id_toggle_enableKeepIView, "enableKeepIView", true);
+ toggle_showRefreshingWhenOverScroll = new TestButton(ResourceTable.Id_toggle_showRefreshingWhenOverScroll, "showRefreshingWhenOS", true);
+ toggle_showLoadingWhenOverScroll = new TestButton(ResourceTable.Id_toggle_showLoadingWhenOverScroll, "showLoadingWhenOS", true);
+ toggle_floatRefresh = new TestButton(ResourceTable.Id_toggle_floatRefresh, "floatRefresh", false);
+ toggle_autoLoadMore = new TestButton(ResourceTable.Id_toggle_autoLoadMore, "autoLoadMore", false);
+ toggle_enableRefresh = new TestButton(ResourceTable.Id_toggle_enableRefresh,"enableRefresh",true);
+
+ top_root = (DirectionalLayout) findComponentById(ResourceTable.Id_top_root);
+ listview_header_text = (DirectionalLayout) findComponentById(com.lcodecore.tkrefreshlayout.ResourceTable.Id_listview_header_text); // 功能3 箭头和提示刷新
+ mStatusTextView = (Text) findComponentById(com.lcodecore.tkrefreshlayout.ResourceTable.Id_refresh_status_textview);
+ mArrowImageView = (Image) findComponentById(com.lcodecore.tkrefreshlayout.ResourceTable.Id_listview_header_arrow);
+ componentContainer = (DirectionalLayout) findComponentById(com.lcodecore.tkrefreshlayout.ResourceTable.Id_frame_container);
+ frameAnimationElement = new FrameAnimationElement(this, ResourceTable.Graphic_anim_loading_view);
+
+
+ loading_more = (Text) findComponentById(ResourceTable.Id_loading_more);
+ direc_layout = (DirectionalLayout) findComponentById(ResourceTable.Id_direc_layout);
+ mRecyclerView = (XRecyclerView) findComponentById(ResourceTable.Id_xRecyclerView);
+ mRecyclerView.setPullRefreshEnabled(true);
+ mRecyclerView.setLoadingMoreEnabled(true);
+ mRecyclerView.setHeadFootStyle(3);
+ mRecyclerView.setSListener(this); // 设置回调
+
+ loading_view = (DirectionalLayout) findComponentById(ResourceTable.Id_loading_view);
+ // 默认进度条的位置
+ loading_view.setScaleX(0);
+ loading_view.setScaleY(0);
+ loading_view.setPosition(-100, -100);
+
+ root = findComponentById(ResourceTable.Id_root);
+ root.setTouchEventListener(this::onTouchEvent);
+
+ refreshCard();
+ scienceAdapter = new ScienceAdapter(this,cards,ResourceTable.Layout_item_science);
+ scienceAdapter.setOnItemClickListener(new XRecyclerView.RecyclerAdapter.OnItemClickListener() {
+ @Override
+ public void onItemClick(Component component, int position) {
+ DeviceUtils.showToast(TestAbility.this,"点击了List第" + position + "个");
+ }
+ });
+ mRecyclerView.setItemProvider(scienceAdapter);
+ scienceAdapter.setNumColumns(2);
+ mRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {
+ @Override
+ public void onRefresh() {
+ TaskDispatcher globalTaskDispatcher = getUITaskDispatcher();
+ globalTaskDispatcher.delayDispatch(() -> {
+ cards.clear();
+ refreshCard();
+ scienceAdapter.notifyDataChanged();
+ if (mRecyclerView != null) {
+ mRecyclerView.refreshComplete();
+ }
+ }, 3000);
+ }
+
+ @Override
+ public void onLoadMore() {
+ mRecyclerView.setPosition(cards.size(),cards.size());
+ loading_more.setVisibility(VISIBLE);
+
+ TaskDispatcher globalTaskDispatcher = getUITaskDispatcher();
+ globalTaskDispatcher.delayDispatch(() -> {
+ loadMoreCard();
+ direc_layout.invalidate();
+ mRecyclerView.loadMoreComplete();
+ loading_more.setVisibility(Component.HIDE);
+ scienceAdapter.notifyDataChanged();
+ }, 3000);
+ }
+ });
+
+ mRecyclerView.addScrolledListener(new Component.ScrolledListener() {
+ @Override
+ public void onContentScrolled(Component component, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
+ isTop = scrollY == 0;
+ }
+ });
+ }
+
+ public void refreshCard() {
+ cards.add(new Card("genetics", "", ResourceTable.Media_science1));
+ cards.add(new Card("globe", "", ResourceTable.Media_science2));
+ cards.add(new Card("lab-flask-leaf", "", ResourceTable.Media_science3));
+ cards.add(new Card("magnet", "", ResourceTable.Media_science4));
+ cards.add(new Card("microscope", "", ResourceTable.Media_science5));
+ cards.add(new Card("moon", "", ResourceTable.Media_science6));
+ cards.add(new Card("telescope", "", ResourceTable.Media_science7));
+ cards.add(new Card("satellite", "", ResourceTable.Media_science8));
+ cards.add(new Card("Newtons-cradle", "", ResourceTable.Media_science9));
+ cards.add(new Card("nuclear-symbol", "", ResourceTable.Media_science10));
+ cards.add(new Card("Newtons-cradle", "", ResourceTable.Media_science9));
+ cards.add(new Card("nuclear-symbol", "", ResourceTable.Media_science10));
+ }
+
+ public void loadMoreCard() {
+ cards.add(new Card("genetics", "", ResourceTable.Media_science1));
+ cards.add(new Card("globe", "", ResourceTable.Media_science2));
+ cards.add(new Card("lab-flask-leaf", "", ResourceTable.Media_science3));
+ cards.add(new Card("magnet", "", ResourceTable.Media_science4));
+ cards.add(new Card("microscope", "", ResourceTable.Media_science5));
+ cards.add(new Card("moon", "", ResourceTable.Media_science6));
+ cards.add(new Card("telescope", "", ResourceTable.Media_science7));
+ cards.add(new Card("satellite", "", ResourceTable.Media_science8));
+ cards.add(new Card("Newtons-cradle", "", ResourceTable.Media_science9));
+ cards.add(new Card("nuclear-symbol", "", ResourceTable.Media_science10));
+ }
+
+ @Override
+ public void onClick(Component component) {
+ switch (component.getId()) {
+ case ResourceTable.Id_toggle_enableLoadmore: // 加载更多
+ toggle_enableLoadmore.toggle();
+ mRecyclerView.setLoadingMoreEnabled(toggle_enableLoadmore.flag);
+
+ break;
+ case ResourceTable.Id_toggle_pureScrollMode_on: // 取消刷新和加载,有上下滚动效果
+ toggle_pureScrollMode_on.toggle();
+ mRecyclerView.setPullRefreshEnabled(false);
+ mRecyclerView.setLoadingMoreEnabled(false);
+ mRecyclerView.setReboundEffect(true);
+
+ break;
+ case ResourceTable.Id_toggle_overScrollTopShow: // 超过滚动顶部显示
+ toggle_overScrollTopShow.toggle();
+ break;
+ case ResourceTable.Id_toggle_osFooterShow: // 底部显示
+ toggle_osFooterShow.toggle();
+ break;
+ case ResourceTable.Id_toggle_enableOverScroll: // 启用过度滚动
+ toggle_enableOverScroll.toggle();
+ mRecyclerView.setReboundEffect(true);
+ break;
+ case ResourceTable.Id_toggle_enableKeepIView: // 禁用底部操作
+ toggle_enableKeepIView.toggle();
+ mRecyclerView.setLoadingMoreEnabled(false);
+ break;
+ case ResourceTable.Id_toggle_showRefreshingWhenOverScroll:// 显示刷新
+ toggle_showRefreshingWhenOverScroll.toggle();
+ mRecyclerView.setPullRefreshEnabled(true);
+ mRecyclerView.setLoadingMoreEnabled(true);
+ break;
+ case ResourceTable.Id_toggle_showLoadingWhenOverScroll:// 显示加载
+ toggle_showLoadingWhenOverScroll.toggle();
+ mRecyclerView.setPullRefreshEnabled(true);
+ mRecyclerView.setLoadingMoreEnabled(true);
+ break;
+ case ResourceTable.Id_toggle_floatRefresh:
+ toggle_floatRefresh.toggle();
+
+ if(component2 == null) {
+ component2 = new Component(getContext());
+ component2.setWidth(80);
+ component2.setHeight(80);
+ component2.setMarginBottom(10);
+ component2.setBackground(frameAnimationElement);
+ componentContainer.addComponent(component2);
+ frameAnimationElement.start();
+ }
+
+ if (toggle_floatRefresh.flag) {
+ mRecyclerView.setTouchEventListener(this);
+ } else {
+ mRecyclerView.setTouchEventListener(null);
+ }
+ break;
+ case ResourceTable.Id_toggle_autoLoadMore:
+ toggle_autoLoadMore.toggle();
+ mRecyclerView.setPullRefreshEnabled(true);
+ mRecyclerView.setLoadingMoreEnabled(true);
+ break;
+ case ResourceTable.Id_toggle_enableRefresh:
+ toggle_enableRefresh.toggle();
+ mRecyclerView.setPullRefreshEnabled(toggle_enableRefresh.flag);
+ }
+ }
+
+ class TestButton {
+ private Button button;
+ private boolean flag;
+ private String text;
+
+ public TestButton(int id, String text, boolean flag) {
+ button = (Button) findComponentById(id);
+ this.text = text;
+ this.flag = flag;
+ button.setClickedListener(TestAbility.this);
+ button.setText(text + "->" + flag);
+ }
+
+ public void toggle() {
+ flag = !flag;
+ button.setText(text + "->" + flag);
+ }
+ }
+
+ private float downY;
+ private float moveY;
+ private float mOffsetY;
+ @Override
+ public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
+ switch (touchEvent.getAction()) {
+ case PRIMARY_POINT_DOWN:
+ if (isTop && timeRecord()) {
+ downY = touchEvent.getPointerScreenPosition(0).getY();
+ }
+ return true;
+ case POINT_MOVE:
+ if (scrolltop == 1) {
+ if (timeRecord()) {
+ mArrowImageView.setRotation(0);
+ moveY = touchEvent.getPointerScreenPosition(touchEvent.getIndex()).getY();
+ mOffsetY = Math.min((moveY - downY), 500);
+ if (mOffsetY > 10 && isTop && (moveY - downY) < 500) {
+ loading_view.setScaleX(0.85f);
+ loading_view.setScaleY(0.85f);
+
+ mOffsetY = (moveY - downY);
+ loading_view.setPosition(0, (int) mOffsetY);
+ }
+ }
+ }
+ return true;
+ case PRIMARY_POINT_UP:
+ if (scrolltop == 1) {
+ if (timeRecord()) {
+ mArrowImageView.setRotation(180);
+ mOffsetY = Math.min((moveY - downY), 500);
+ if (mOffsetY < 200) {
+ AnimatorProperty animatorProperty2 = loading_view.createAnimatorProperty();
+ animatorProperty2.moveFromY(mOffsetY).moveToY(0).setDuration(500).setDelay(100);
+ animatorProperty2.start();
+
+ } else {
+ moveY = touchEvent.getPointerScreenPosition(touchEvent.getIndex()).getY();
+ animationFromTo(); //回退位置
+ // 设置 开始动画时间戳
+ lastClickTime = System.currentTimeMillis();
+ new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
+ @Override
+ public void run() {
+ setTopHide();
+ lastClickTime = 0;
+ root.invalidate();
+ }
+ }, 2000);
+ }
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void onListener(int type) {
+ if(type == 1){
+ scrolltop = 0;
+ } else if(type == 0){
+ scrolltop = 1;
+ }
+ }
+
+ public void setTopHide() {
+ AnimatorProperty animatorProperty = loading_view.createAnimatorProperty();
+ animatorProperty.moveFromY(100).moveToY(-100).setDuration(500).setDelay(100);
+ animatorProperty.start();
+
+ new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
+ @Override
+ public void run() {
+ mArrowImageView.setVisibility(VISIBLE);
+ componentContainer.setVisibility(HIDE);
+ }
+ }, 500);
+ }
+
+ public void animationFromTo(){
+ AnimatorProperty animatorProperty = loading_view.createAnimatorProperty();
+ animatorProperty.moveFromY(mOffsetY).moveToY(150).setDuration(500).setDelay(100);
+ animatorProperty.start();
+ new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
+ @Override
+ public void run() {
+ mArrowImageView.setVisibility(HIDE);
+ componentContainer.setVisibility(VISIBLE);
+ }
+ }, 500);
+ }
+
+ // 两次点击按钮之间的点击间隔不能少于1000毫秒
+ private final int MIN_CLICK_DELAY_TIME = 2000;
+ private long lastClickTime = 0;
+ public boolean timeRecord(){
+ if(lastClickTime == 0){
+ return true;
+ }
+ long curClickTime = System.currentTimeMillis();
+ if((curClickTime - lastClickTime) >= MIN_CLICK_DELAY_TIME) {
+ // 超过点击间隔后再将lastClickTime重置为当前点击时间
+ lastClickTime = curClickTime;
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/WebAbility.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/WebAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..80db94ca520530525c4e982acb9cf4a2b389fc53
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/WebAbility.java
@@ -0,0 +1,159 @@
+package com.lcodecore.twinklingrefreshlayout;
+import com.lcodecore.tkrefreshlayout.processor.loading.LoadingView;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+import ohos.agp.components.StackLayout;
+import ohos.agp.components.webengine.Navigator;
+import ohos.agp.components.webengine.ResourceError;
+import ohos.agp.components.webengine.ResourceRequest;
+import ohos.agp.components.webengine.WebAgent;
+import ohos.agp.components.webengine.WebView;
+import ohos.agp.window.service.Display;
+import ohos.agp.window.service.DisplayAttributes;
+import ohos.agp.window.service.DisplayManager;
+import ohos.app.Context;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+import ohos.global.resource.NotExistException;
+import ohos.global.resource.ResourceManager;
+import ohos.global.resource.WrongTypeException;
+import ohos.media.image.PixelMap;
+import ohos.multimodalinput.event.TouchEvent;
+
+import java.io.IOException;
+import java.util.Optional;
+import static ohos.multimodalinput.event.TouchEvent.POINT_MOVE;
+import static ohos.multimodalinput.event.TouchEvent.PRIMARY_POINT_DOWN;
+import static ohos.multimodalinput.event.TouchEvent.PRIMARY_POINT_UP;
+
+public class WebAbility extends Ability implements Component.TouchEventListener {
+ private StackLayout top_view;
+ private WebView mWebView;
+ private LoadingView loadingView;
+ private int widthPm;
+ private Navigator navigator;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_web);
+ Optional
+ display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());
+ DisplayAttributes displayAttributes = display.get().getAttributes();
+ widthPm = displayAttributes.width;
+
+ loadingView = (LoadingView) findComponentById(ResourceTable.Id_progress_loading);
+ loadingView.setBindStateChangedListener(loadingView);
+ loadingView.setPaintcolor(1);
+ loadingView.setSize(45);
+ loadingView.stopAnimation();
+
+ new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
+ @Override
+ public void run() {
+ AnimatorProperty animatorProperty = loadingView.createAnimatorProperty();
+ animatorProperty.setDuration(500).setDelay(100).scaleX(0).scaleY(0);
+ animatorProperty.start();
+ mWebView.setVisibility(Component.VISIBLE);
+ }
+ },4000);
+
+ loadingView.setScaleX(0.9f);
+ loadingView.setScaleY(0.9f);
+
+ top_view = (StackLayout) findComponentById(ResourceTable.Id_top_view);
+
+ mWebView = (WebView) findComponentById(ResourceTable.Id_webView);
+ mWebView.getWebConfig().setJavaScriptPermit(true);
+ mWebView.load(getString(this, ResourceTable.String_weburl));
+ navigator = mWebView.getNavigator();
+ mWebView.setWebAgent(new WebAgent() {
+ @Override
+ public void onLoadingPage(WebView webview, String url, PixelMap favicon) {
+ super.onLoadingPage(webview, url, favicon);
+ // 页面开始加载时自定义处理
+ }
+
+ @Override
+ public void onPageLoaded(WebView webview, String url) {
+ super.onPageLoaded(webview, url);
+ // 页面加载结束后自定义处理
+ }
+
+ @Override
+ public void onLoadingContent(WebView webview, String url) {
+ super.onLoadingContent(webview, url);
+ // 加载资源时自定义处理
+ }
+
+ @Override
+ public void onError(WebView webview, ResourceRequest request, ResourceError error) {
+ super.onError(webview, request, error);
+ // 发生错误时自定义处理
+ }
+ });
+ }
+
+ @Override
+ protected void onBackPressed() {
+ if (navigator.canGoBack()) {
+ navigator.goBack();
+ }else{
+ terminateAbility();
+ }
+ }
+
+ private float downY;
+ private float moveY;
+ private float mOffsetY;
+ @Override
+ public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
+ switch (touchEvent.getAction()){
+ case PRIMARY_POINT_DOWN:
+ downY = touchEvent.getPointerPosition(0).getY();
+ return true;
+ case POINT_MOVE:
+ moveY = touchEvent.getPointerPosition(touchEvent.getIndex()).getY();
+ if ((moveY - downY) > 1 && (moveY - downY) < 700) {
+ System.out.println("============"+(moveY - downY));
+ mOffsetY = (moveY - downY);
+ }
+ return true;
+ case PRIMARY_POINT_UP:
+ moveY = touchEvent.getPointerPosition(touchEvent.getIndex()).getY();
+ new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
+ @Override
+ public void run() {
+ }
+ },3000);
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * get string
+ *
+ * @param context the context
+ * @param id the string id
+ * @return string of the given id
+ */
+ public static String getString(Context context, int id) {
+ String result = "";
+ if (context == null) {
+ return result;
+ }
+ ResourceManager manager = context.getResourceManager();
+ if (manager == null) {
+ return result;
+ }
+ try {
+ result = manager.getElement(id).getString();
+ } catch (IOException | WrongTypeException | NotExistException e) {
+ return result;
+ }
+ return result;
+ }
+}
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/FoodAdapter.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/FoodAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..9de5bfb1768b82c26d43c24808f3c2830e2100da
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/FoodAdapter.java
@@ -0,0 +1,79 @@
+package com.lcodecore.twinklingrefreshlayout.adapter;
+
+import com.lcodecore.tkrefreshlayout.XRecyclerView;
+import com.lcodecore.twinklingrefreshlayout.ResourceTable;
+import com.lcodecore.twinklingrefreshlayout.beans.Food;
+import ohos.agp.colors.RgbColor;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.Text;
+import ohos.agp.components.element.ShapeElement;
+import ohos.app.Context;
+
+import java.util.List;
+
+/**
+ * Created by lcodecore on 2016/12/6.
+ */
+public class FoodAdapter extends XRecyclerView.RecyclerAdapter {
+ /**
+ * Adapter构造方法
+ *
+ * @param context 上下文
+ * @param foods 列表数据
+ * @param layoutId 组件ID
+ */
+ public FoodAdapter(Context context, List foods, int layoutId) {
+ super(context, foods, layoutId);
+ }
+
+ @Override
+ public List getData() {
+ return super.getData();
+ }
+
+ @Override
+ public int getCount() {
+ return super.getCount();
+ }
+
+ @Override
+ public T getItem(int position) {
+ return super.getItem(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return super.getItemId(position);
+ }
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer parent) {
+ return super.getComponent(position, convertComponent, parent);
+ }
+
+ @Override
+ public void setNumColumns(int numColumns) {
+ super.setNumColumns(numColumns);
+ }
+
+ @Override
+ public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
+ super.setOnItemClickListener(onItemClickListener);
+ }
+
+ @Override
+ public void bind(ViewHolder holder, T cards, int position) {
+ Food car = (Food) cards;
+ ShapeElement element = new ShapeElement();
+ element.setRgbColor(RgbColor.fromArgbInt(0xffffffff));
+ element.setCornerRadius(10);
+ holder.getView(ResourceTable.Id_derection_bg).setBackground(element);
+ holder.getView(ResourceTable.Id_tv_food).setText(car.title);
+ holder.getView(ResourceTable.Id_tv_info).setText(car.info);
+ holder.getView(ResourceTable.Id_avatar).setPixelMap(car.avatar_id);
+ holder.getView(ResourceTable.Id_iv_food).setPixelMap(car.imageSrc);
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/MusicAdapter.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/MusicAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4024e1fed73d946cc35e919f6667709dd06929e
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/MusicAdapter.java
@@ -0,0 +1,80 @@
+package com.lcodecore.twinklingrefreshlayout.adapter;
+
+import com.lcodecore.tkrefreshlayout.XRecyclerView;
+import com.lcodecore.twinklingrefreshlayout.ResourceTable;
+import com.lcodecore.twinklingrefreshlayout.beans.Card;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.DependentLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.Text;
+import ohos.app.Context;
+import java.util.List;
+
+/**
+ * Created by lcodecore on 2016/12/6.
+ */
+public class MusicAdapter extends XRecyclerView.RecyclerAdapter {
+ /**
+ * Adapter构造方法
+ *
+ * @param context 上下文
+ * @param cards 列表数据
+ * @param layoutId 组件ID
+ */
+ public MusicAdapter(Context context, List cards, int layoutId) {
+ super(context, cards, layoutId);
+ }
+
+ @Override
+ public List getData() {
+ return super.getData();
+ }
+
+ @Override
+ public int getCount() {
+ return super.getCount();
+ }
+
+ @Override
+ public T getItem(int position) {
+ return super.getItem(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return super.getItemId(position);
+ }
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer parent) {
+ return super.getComponent(position, convertComponent, parent);
+ }
+
+ @Override
+ public void setNumColumns(int numColumns) {
+ super.setNumColumns(numColumns);
+ }
+
+ @Override
+ public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
+ super.setOnItemClickListener(onItemClickListener);
+ }
+
+ @Override
+ public void bind(ViewHolder holder, T cards, int position) {
+ System.out.println("==============================----"+position);
+ Card car = (Card) cards;
+ if(position == 0){
+ holder.getView(ResourceTable.Id_background).setVisibility(Component.VISIBLE);
+ holder.getView(ResourceTable.Id_content).setVisibility(Component.HIDE);
+ }else {
+ holder.getView(ResourceTable.Id_background).setVisibility(Component.HIDE);
+ holder.getView(ResourceTable.Id_content).setVisibility(Component.VISIBLE);
+ holder.getView(ResourceTable.Id_tv_song).setText(car.title);
+
+ holder.getView(ResourceTable.Id_tv_singer).setText(car.info);
+ holder.getView(ResourceTable.Id_avatar).setPixelMap(car.imageSrc);
+ }
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/PhotoAdapter.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/PhotoAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..f53b464470550fb6f96b8cf2024fd456ba5ee228
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/PhotoAdapter.java
@@ -0,0 +1,81 @@
+package com.lcodecore.twinklingrefreshlayout.adapter;
+
+import com.lcodecore.tkrefreshlayout.XRecyclerView;
+import com.lcodecore.twinklingrefreshlayout.ResourceTable;
+import com.lcodecore.twinklingrefreshlayout.beans.Photo;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.Text;
+import ohos.app.Context;
+
+import java.util.List;
+
+/**
+ * Created by lcodecore on 2016/12/7.
+ */
+public class PhotoAdapter extends XRecyclerView.RecyclerAdapter {
+ /**
+ * Adapter构造方法
+ *
+ * @param context 上下文
+ * @param photos 列表数据
+ * @param layoutId 组件ID
+ */
+ public PhotoAdapter(Context context, List photos, int layoutId) {
+ super(context, photos, layoutId);
+ }
+
+ @Override
+ public List getData() {
+ return super.getData();
+ }
+
+ @Override
+ public int getCount() {
+ return super.getCount();
+ }
+
+ @Override
+ public T getItem(int position) {
+ return super.getItem(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return super.getItemId(position);
+ }
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer parent) {
+ return super.getComponent(position, convertComponent, parent);
+ }
+
+ @Override
+ public void setNumColumns(int numColumns) {
+ super.setNumColumns(numColumns);
+ }
+
+ @Override
+ public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
+ super.setOnItemClickListener(onItemClickListener);
+ }
+
+ @Override
+ public void bind(ViewHolder holder, T photos, int position) {
+ Photo photo = (Photo) photos;
+ setNumColumns(2);
+ if(position == 0){
+ setNumColumns(1);
+ holder.getView(ResourceTable.Id_iv_phototop).setVisibility(Component.VISIBLE);
+ holder.getView(ResourceTable.Id_photo_content).setVisibility(Component.HIDE);
+ }else {
+ holder.getView(ResourceTable.Id_iv_phototop).setVisibility(Component.HIDE);
+ holder.getView(ResourceTable.Id_photo_content).setVisibility(Component.VISIBLE);
+
+ holder.getView(ResourceTable.Id_tv_info).setText(photo.name);
+ holder.getView(ResourceTable.Id_iv_pic).setPixelMap(photo.imgSrc);
+ }
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/PhotoAnimationAdapter.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/PhotoAnimationAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..d3676f9c0ccd73b8ec204f9d462e57b0e87e36f9
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/PhotoAnimationAdapter.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.twinklingrefreshlayout.adapter;
+
+import com.lcodecore.tkrefreshlayout.XRecyclerView;
+import com.lcodecore.twinklingrefreshlayout.ResourceTable;
+import com.lcodecore.twinklingrefreshlayout.beans.Photo;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.Image;
+import ohos.agp.components.Text;
+import ohos.app.Context;
+
+import java.util.List;
+
+/**
+ * MyApplication类
+ *
+ * @param animation
+ * @since 2021-07-19
+ */
+public class PhotoAnimationAdapter extends XRecyclerView.RecyclerAdapter {
+ /**
+ * Adapter构造方法
+ *
+ * @param context 上下文
+ * @param photos 列表数据
+ * @param layoutId 组件ID
+ */
+ public PhotoAnimationAdapter(Context context, List photos, int layoutId) {
+ super(context, photos, layoutId);
+ }
+
+ @Override
+ public List getData() {
+ return super.getData();
+ }
+
+ @Override
+ public int getCount() {
+ return super.getCount();
+ }
+
+ @Override
+ public T getItem(int position) {
+ return super.getItem(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return super.getItemId(position);
+ }
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer parent) {
+ return super.getComponent(position, convertComponent, parent);
+ }
+
+ @Override
+ public void setNumColumns(int numColumns) {
+ super.setNumColumns(numColumns);
+ }
+
+ @Override
+ public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
+ super.setOnItemClickListener(onItemClickListener);
+ }
+
+ @Override
+ public void bind(ViewHolder holder, T photos, int position) {
+ Photo photo = (Photo) photos;
+ holder.getView(ResourceTable.Id_tv_info).setText(photo.name);
+ holder.getView(ResourceTable.Id_iv_pic).setPixelMap(photo.imgSrc);
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/ScienceAdapter.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/ScienceAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..dabc08e1ebb9a380e0d755171e76f261c1633792
--- /dev/null
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/ScienceAdapter.java
@@ -0,0 +1,77 @@
+package com.lcodecore.twinklingrefreshlayout.adapter;
+
+import com.lcodecore.tkrefreshlayout.XRecyclerView;
+import com.lcodecore.twinklingrefreshlayout.ResourceTable;
+import com.lcodecore.twinklingrefreshlayout.beans.Card;
+import ohos.agp.colors.RgbColor;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.Text;
+import ohos.agp.components.element.ShapeElement;
+import ohos.app.Context;
+
+import java.util.List;
+/**
+ * Created by lcodecore on 2016/12/7.
+ */
+public class ScienceAdapter extends XRecyclerView.RecyclerAdapter {
+ /**
+ * Adapter构造方法
+ *
+ * @param context 上下文
+ * @param foods 列表数据
+ * @param layoutId 组件ID
+ */
+ public ScienceAdapter(Context context, List foods, int layoutId) {
+ super(context, foods, layoutId);
+ }
+
+ @Override
+ public List getData() {
+ return super.getData();
+ }
+
+ @Override
+ public int getCount() {
+ return super.getCount();
+ }
+
+ @Override
+ public T getItem(int position) {
+ return super.getItem(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return super.getItemId(position);
+ }
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer parent) {
+ return super.getComponent(position, convertComponent, parent);
+ }
+
+ @Override
+ public void setNumColumns(int numColumns) {
+ super.setNumColumns(numColumns);
+ }
+
+ @Override
+ public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
+ super.setOnItemClickListener(onItemClickListener);
+ }
+
+ @Override
+ public void bind(ViewHolder holder, T cards, int position) {
+ Card car = (Card) cards;
+ ShapeElement element = new ShapeElement();
+ element.setRgbColor(RgbColor.fromArgbInt(0xffffffff));
+ element.setCornerRadius(5);
+ holder.getView(ResourceTable.Id_science_bg).setBackground(element);
+
+ holder.getView(ResourceTable.Id_tv_name).setText(car.title);
+ holder.getView(ResourceTable.Id_iv_cover).setPixelMap(car.imageSrc);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Card.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Card.java
similarity index 100%
rename from app/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Card.java
rename to entry/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Card.java
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Food.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Food.java
similarity index 99%
rename from app/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Food.java
rename to entry/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Food.java
index 6530d0683736eb7c748697900aabca1e255101ca..45eecff9098a94570630997f52faa9d495cbbd06 100644
--- a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Food.java
+++ b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Food.java
@@ -16,5 +16,4 @@ public class Food {
this.imageSrc = imageSrc;
this.avatar_id = avatar_id;
}
-
}
diff --git a/app/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Photo.java b/entry/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Photo.java
similarity index 100%
rename from app/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Photo.java
rename to entry/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Photo.java
diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..5f4047564b98f96bfd9891f5e1e9811d008307a9
--- /dev/null
+++ b/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,128 @@
+{
+ "string": [
+ {
+ "name": "entry_MainAbility",
+ "value": "entry_MainAbility"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "mainability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "musiclistviewfixedheaderability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "musiclistviewfixedheaderability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_MusicListViewFixedHeaderAbility",
+ "value": "entry_MusicListViewFixedHeaderAbility"
+ },
+ {
+ "name": "foodability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "foodability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_FoodAbility",
+ "value": "entry_FoodAbility"
+ },
+ {
+ "name": "normalviewability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "normalviewability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_NormalViewAbility",
+ "value": "entry_NormalViewAbility"
+ },
+ {
+ "name": "scienceability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "scienceability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_ScienceAbility",
+ "value": "entry_ScienceAbility"
+ },
+ {
+ "name": "storyability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "storyability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_StoryAbility",
+ "value": "entry_StoryAbility"
+ },
+ {
+ "name": "webability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "webability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_WebAbility",
+ "value": "entry_WebAbility"
+ },
+ {
+ "name": "testability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "testability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_TestAbility",
+ "value": "entry_TestAbility"
+ },
+ {
+ "name": "coordinateability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "coordinateability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_CoordinateAbility",
+ "value": "entry_CoordinateAbility"
+ },
+ {
+ "name": "photoability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "photoability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_PhotoAbility",
+ "value": "entry_PhotoAbility"
+ },
+ {
+ "name": "weburl",
+ "value": "https://dribbble.com/shots"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_coordinate.xml b/entry/src/main/resources/base/graphic/background_ability_coordinate.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a002c2353e78af3a15235e00738328ff566bc085
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_coordinate.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_food.xml b/entry/src/main/resources/base/graphic/background_ability_food.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a002c2353e78af3a15235e00738328ff566bc085
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_food.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_main.xml b/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_music_list_view_fixed_header.xml b/entry/src/main/resources/base/graphic/background_ability_music_list_view_fixed_header.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a002c2353e78af3a15235e00738328ff566bc085
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_music_list_view_fixed_header.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_normal_view.xml b/entry/src/main/resources/base/graphic/background_ability_normal_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a002c2353e78af3a15235e00738328ff566bc085
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_normal_view.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_photo.xml b/entry/src/main/resources/base/graphic/background_ability_photo.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a002c2353e78af3a15235e00738328ff566bc085
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_photo.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_science.xml b/entry/src/main/resources/base/graphic/background_ability_science.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a002c2353e78af3a15235e00738328ff566bc085
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_science.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_story.xml b/entry/src/main/resources/base/graphic/background_ability_story.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a002c2353e78af3a15235e00738328ff566bc085
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_story.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_test.xml b/entry/src/main/resources/base/graphic/background_ability_test.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a002c2353e78af3a15235e00738328ff566bc085
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_test.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_web.xml b/entry/src/main/resources/base/graphic/background_ability_web.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a002c2353e78af3a15235e00738328ff566bc085
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_web.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/circle_background.xml b/entry/src/main/resources/base/graphic/circle_background.xml
new file mode 100644
index 0000000000000000000000000000000000000000..407f53fcc5da3f3f6deea3041e9fedec2c55e339
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/circle_background.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_coordinate.xml b/entry/src/main/resources/base/layout/ability_coordinate.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6f1f8bb9fec10d072845ba029afbb3d5440fec56
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_coordinate.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_food.xml b/entry/src/main/resources/base/layout/ability_food.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c6b2eec7a2c62ed142c2ef1d674fe9a77b54e376
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_food.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_main.xml b/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b3481886d1a43383cb1d254da71fb74408140dc6
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_music.xml b/entry/src/main/resources/base/layout/ability_music.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2e03f76b1ca420357640ef632064f861ae89971e
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_music.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_normal_view.xml b/entry/src/main/resources/base/layout/ability_normal_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3404eb4cde85ad1183f25e1588a66e3f632805f8
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_normal_view.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_photo.xml b/entry/src/main/resources/base/layout/ability_photo.xml
new file mode 100644
index 0000000000000000000000000000000000000000..813e5a39b9bca4390c2fb7f9bd7fe847b1c7229c
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_photo.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_science.xml b/entry/src/main/resources/base/layout/ability_science.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7f0a5a0fc2449718a4e358ea7973a3875f676d91
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_science.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_story.xml b/entry/src/main/resources/base/layout/ability_story.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e80b6b4e4b6717d1a8a9ebec162380f725ecd1de
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_story.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_test.xml b/entry/src/main/resources/base/layout/ability_test.xml
new file mode 100644
index 0000000000000000000000000000000000000000..efd3204d90b6650920ed8ed98f8303e197188eee
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_test.xml
@@ -0,0 +1,290 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_web.xml b/entry/src/main/resources/base/layout/ability_web.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c4659e5e7dbd4341dfd87f96439f812dbb913c5a
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_web.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/content_main.xml b/entry/src/main/resources/base/layout/content_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..42a456f07ffa06d97a09b1881f9f8fdc1773ac28
--- /dev/null
+++ b/entry/src/main/resources/base/layout/content_main.xml
@@ -0,0 +1,152 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/dialog_web.xml b/entry/src/main/resources/base/layout/dialog_web.xml
new file mode 100644
index 0000000000000000000000000000000000000000..da21df48ac29abecb92bdbc3944e2ed6909db62e
--- /dev/null
+++ b/entry/src/main/resources/base/layout/dialog_web.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/header_animi.xml b/entry/src/main/resources/base/layout/header_animi.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8e405724351c386276196de6d5712d3b232b4b99
--- /dev/null
+++ b/entry/src/main/resources/base/layout/header_animi.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/header_music.xml b/entry/src/main/resources/base/layout/header_music.xml
new file mode 100644
index 0000000000000000000000000000000000000000..36f1f2b4660494759d3b7875135d12eb51ff7c24
--- /dev/null
+++ b/entry/src/main/resources/base/layout/header_music.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/item_food.xml b/entry/src/main/resources/base/layout/item_food.xml
new file mode 100644
index 0000000000000000000000000000000000000000..92b80027e05e6f806fe2b4b4c40c4f6fca5e1fc0
--- /dev/null
+++ b/entry/src/main/resources/base/layout/item_food.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/item_music.xml b/entry/src/main/resources/base/layout/item_music.xml
new file mode 100644
index 0000000000000000000000000000000000000000..48d0b2edb7355d900b3b982d9f60ce0836237e94
--- /dev/null
+++ b/entry/src/main/resources/base/layout/item_music.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/item_photo.xml b/entry/src/main/resources/base/layout/item_photo.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b0fb9bbffa3fff4212253435ff4f715fd2715c10
--- /dev/null
+++ b/entry/src/main/resources/base/layout/item_photo.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/item_photoAnima.xml b/entry/src/main/resources/base/layout/item_photoAnima.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c847cffece34fac0fde32da436fee784a72e8523
--- /dev/null
+++ b/entry/src/main/resources/base/layout/item_photoAnima.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/item_science.xml b/entry/src/main/resources/base/layout/item_science.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fcfb63f4420b061d80a11c988c44ab23ecda6ee5
--- /dev/null
+++ b/entry/src/main/resources/base/layout/item_science.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/item_story.xml b/entry/src/main/resources/base/layout/item_story.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ef3503ff469f114fa89752013174deec4c6df227
--- /dev/null
+++ b/entry/src/main/resources/base/layout/item_story.xml
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/test_headtitle.xml b/entry/src/main/resources/base/layout/test_headtitle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..736375f128a9f70aecd231e46f6af27ee9bef25c
--- /dev/null
+++ b/entry/src/main/resources/base/layout/test_headtitle.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/top_title.xml b/entry/src/main/resources/base/layout/top_title.xml
new file mode 100644
index 0000000000000000000000000000000000000000..feb8b3cb7467ef26a28ae8d6b8bf43a75a066926
--- /dev/null
+++ b/entry/src/main/resources/base/layout/top_title.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/top_title_food.xml b/entry/src/main/resources/base/layout/top_title_food.xml
new file mode 100644
index 0000000000000000000000000000000000000000..29a5a86d2dc13be147233236625d5a48ee852a62
--- /dev/null
+++ b/entry/src/main/resources/base/layout/top_title_food.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/top_title_photo.xml b/entry/src/main/resources/base/layout/top_title_photo.xml
new file mode 100644
index 0000000000000000000000000000000000000000..97f0576cb59e002c868e7c2a5cfdee0810345ab2
--- /dev/null
+++ b/entry/src/main/resources/base/layout/top_title_photo.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-xhdpi/avatar0.jpg b/entry/src/main/resources/base/media/avatar0.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/avatar0.jpg
rename to entry/src/main/resources/base/media/avatar0.jpg
diff --git a/app/src/main/res/drawable-xhdpi/avatar1.jpg b/entry/src/main/resources/base/media/avatar1.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/avatar1.jpg
rename to entry/src/main/resources/base/media/avatar1.jpg
diff --git a/app/src/main/res/drawable-xhdpi/avatar2.jpg b/entry/src/main/resources/base/media/avatar2.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/avatar2.jpg
rename to entry/src/main/resources/base/media/avatar2.jpg
diff --git a/app/src/main/res/drawable-xhdpi/avatar3.jpg b/entry/src/main/resources/base/media/avatar3.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/avatar3.jpg
rename to entry/src/main/resources/base/media/avatar3.jpg
diff --git a/app/src/main/res/drawable-xhdpi/avatar4.jpg b/entry/src/main/resources/base/media/avatar4.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/avatar4.jpg
rename to entry/src/main/resources/base/media/avatar4.jpg
diff --git a/app/src/main/res/drawable-xhdpi/avatar5.jpg b/entry/src/main/resources/base/media/avatar5.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/avatar5.jpg
rename to entry/src/main/resources/base/media/avatar5.jpg
diff --git a/app/src/main/res/drawable-xhdpi/avatar6.jpg b/entry/src/main/resources/base/media/avatar6.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/avatar6.jpg
rename to entry/src/main/resources/base/media/avatar6.jpg
diff --git a/app/src/main/res/drawable-xhdpi/avatar7.jpg b/entry/src/main/resources/base/media/avatar7.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/avatar7.jpg
rename to entry/src/main/resources/base/media/avatar7.jpg
diff --git a/app/src/main/res/drawable-xhdpi/avatar8.jpg b/entry/src/main/resources/base/media/avatar8.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/avatar8.jpg
rename to entry/src/main/resources/base/media/avatar8.jpg
diff --git a/app/src/main/res/drawable-xhdpi/avatar9.jpg b/entry/src/main/resources/base/media/avatar9.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/avatar9.jpg
rename to entry/src/main/resources/base/media/avatar9.jpg
diff --git a/app/src/main/res/drawable-xhdpi/back.png b/entry/src/main/resources/base/media/back.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/back.png
rename to entry/src/main/resources/base/media/back.png
diff --git a/app/src/main/res/drawable-xhdpi/back_dark.png b/entry/src/main/resources/base/media/back_dark.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/back_dark.png
rename to entry/src/main/resources/base/media/back_dark.png
diff --git a/app/src/main/res/drawable-xhdpi/back_pink.png b/entry/src/main/resources/base/media/back_pink.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/back_pink.png
rename to entry/src/main/resources/base/media/back_pink.png
diff --git a/app/src/main/res/drawable-xhdpi/back_white.png b/entry/src/main/resources/base/media/back_white.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/back_white.png
rename to entry/src/main/resources/base/media/back_white.png
diff --git a/app/src/main/res/drawable/bg_wood.png b/entry/src/main/resources/base/media/bg_wood.png
old mode 100755
new mode 100644
similarity index 100%
rename from app/src/main/res/drawable/bg_wood.png
rename to entry/src/main/resources/base/media/bg_wood.png
diff --git a/app/src/main/res/drawable-xhdpi/food1.jpg b/entry/src/main/resources/base/media/food1.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/food1.jpg
rename to entry/src/main/resources/base/media/food1.jpg
diff --git a/app/src/main/res/drawable-xhdpi/food2.jpg b/entry/src/main/resources/base/media/food2.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/food2.jpg
rename to entry/src/main/resources/base/media/food2.jpg
diff --git a/app/src/main/res/drawable-xhdpi/food3.jpg b/entry/src/main/resources/base/media/food3.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/food3.jpg
rename to entry/src/main/resources/base/media/food3.jpg
diff --git a/app/src/main/res/drawable-xhdpi/food4.jpg b/entry/src/main/resources/base/media/food4.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/food4.jpg
rename to entry/src/main/resources/base/media/food4.jpg
diff --git a/app/src/main/res/drawable-xhdpi/food5.jpg b/entry/src/main/resources/base/media/food5.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/food5.jpg
rename to entry/src/main/resources/base/media/food5.jpg
diff --git a/app/src/main/res/drawable-xxhdpi/ic_create_white_36dp.png b/entry/src/main/resources/base/media/ic_create_white_36dp.png
similarity index 100%
rename from app/src/main/res/drawable-xxhdpi/ic_create_white_36dp.png
rename to entry/src/main/resources/base/media/ic_create_white_36dp.png
diff --git a/entry/src/main/resources/base/media/icon.png b/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/entry/src/main/resources/base/media/icon.png differ
diff --git a/entry/src/main/resources/base/media/iconfont_downgrey.png b/entry/src/main/resources/base/media/iconfont_downgrey.png
new file mode 100644
index 0000000000000000000000000000000000000000..42e1371c1d478465697302e3a160b09af4e3017f
Binary files /dev/null and b/entry/src/main/resources/base/media/iconfont_downgrey.png differ
diff --git a/app/src/main/res/drawable-xhdpi/map.png b/entry/src/main/resources/base/media/map.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/map.png
rename to entry/src/main/resources/base/media/map.png
diff --git a/app/src/main/res/drawable-xhdpi/pager_bg.png b/entry/src/main/resources/base/media/pager_bg.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/pager_bg.png
rename to entry/src/main/resources/base/media/pager_bg.png
diff --git a/app/src/main/res/drawable-xhdpi/photo1.jpg b/entry/src/main/resources/base/media/photo1.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/photo1.jpg
rename to entry/src/main/resources/base/media/photo1.jpg
diff --git a/app/src/main/res/drawable-xhdpi/photo10.jpg b/entry/src/main/resources/base/media/photo10.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/photo10.jpg
rename to entry/src/main/resources/base/media/photo10.jpg
diff --git a/app/src/main/res/drawable-xhdpi/photo2.jpg b/entry/src/main/resources/base/media/photo2.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/photo2.jpg
rename to entry/src/main/resources/base/media/photo2.jpg
diff --git a/app/src/main/res/drawable-xhdpi/photo3.jpg b/entry/src/main/resources/base/media/photo3.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/photo3.jpg
rename to entry/src/main/resources/base/media/photo3.jpg
diff --git a/app/src/main/res/drawable-xhdpi/photo4.jpg b/entry/src/main/resources/base/media/photo4.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/photo4.jpg
rename to entry/src/main/resources/base/media/photo4.jpg
diff --git a/app/src/main/res/drawable-xhdpi/photo5.jpg b/entry/src/main/resources/base/media/photo5.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/photo5.jpg
rename to entry/src/main/resources/base/media/photo5.jpg
diff --git a/app/src/main/res/drawable-xhdpi/photo6.jpg b/entry/src/main/resources/base/media/photo6.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/photo6.jpg
rename to entry/src/main/resources/base/media/photo6.jpg
diff --git a/app/src/main/res/drawable-xhdpi/photo7.jpg b/entry/src/main/resources/base/media/photo7.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/photo7.jpg
rename to entry/src/main/resources/base/media/photo7.jpg
diff --git a/app/src/main/res/drawable-xhdpi/photo8.jpg b/entry/src/main/resources/base/media/photo8.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/photo8.jpg
rename to entry/src/main/resources/base/media/photo8.jpg
diff --git a/app/src/main/res/drawable-xhdpi/photo9.jpg b/entry/src/main/resources/base/media/photo9.jpg
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/photo9.jpg
rename to entry/src/main/resources/base/media/photo9.jpg
diff --git a/app/src/main/res/drawable-xhdpi/play.png b/entry/src/main/resources/base/media/play.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/play.png
rename to entry/src/main/resources/base/media/play.png
diff --git a/app/src/main/res/drawable-xhdpi/play_white.png b/entry/src/main/resources/base/media/play_white.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/play_white.png
rename to entry/src/main/resources/base/media/play_white.png
diff --git a/app/src/main/res/drawable-xhdpi/science1.png b/entry/src/main/resources/base/media/science1.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/science1.png
rename to entry/src/main/resources/base/media/science1.png
diff --git a/app/src/main/res/drawable-xhdpi/science10.png b/entry/src/main/resources/base/media/science10.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/science10.png
rename to entry/src/main/resources/base/media/science10.png
diff --git a/app/src/main/res/drawable-xhdpi/science2.png b/entry/src/main/resources/base/media/science2.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/science2.png
rename to entry/src/main/resources/base/media/science2.png
diff --git a/app/src/main/res/drawable-xhdpi/science3.png b/entry/src/main/resources/base/media/science3.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/science3.png
rename to entry/src/main/resources/base/media/science3.png
diff --git a/app/src/main/res/drawable-xhdpi/science4.png b/entry/src/main/resources/base/media/science4.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/science4.png
rename to entry/src/main/resources/base/media/science4.png
diff --git a/app/src/main/res/drawable-xhdpi/science5.png b/entry/src/main/resources/base/media/science5.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/science5.png
rename to entry/src/main/resources/base/media/science5.png
diff --git a/app/src/main/res/drawable-xhdpi/science6.png b/entry/src/main/resources/base/media/science6.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/science6.png
rename to entry/src/main/resources/base/media/science6.png
diff --git a/app/src/main/res/drawable-xhdpi/science7.png b/entry/src/main/resources/base/media/science7.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/science7.png
rename to entry/src/main/resources/base/media/science7.png
diff --git a/app/src/main/res/drawable-xhdpi/science8.png b/entry/src/main/resources/base/media/science8.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/science8.png
rename to entry/src/main/resources/base/media/science8.png
diff --git a/app/src/main/res/drawable-xhdpi/science9.png b/entry/src/main/resources/base/media/science9.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/science9.png
rename to entry/src/main/resources/base/media/science9.png
diff --git a/app/src/main/res/drawable-xhdpi/wave.png b/entry/src/main/resources/base/media/wave.png
similarity index 100%
rename from app/src/main/res/drawable-xhdpi/wave.png
rename to entry/src/main/resources/base/media/wave.png
diff --git a/entry/src/main/resources/en/element/string.json b/entry/src/main/resources/en/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..b86c33be92443b876bd03ba7bc3c8e5ee2c8caa0
--- /dev/null
+++ b/entry/src/main/resources/en/element/string.json
@@ -0,0 +1,124 @@
+{
+ "string": [
+ {
+ "name": "entry_MainAbility",
+ "value": "entry_MainAbility"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "mainability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_MusicListViewFixedHeaderAbility",
+ "value": "entry_MusicListViewFixedHeaderAbility"
+ },
+ {
+ "name": "musiclistviewfixedheaderability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "musiclistviewfixedheaderability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_FoodAbility",
+ "value": "entry_FoodAbility"
+ },
+ {
+ "name": "foodability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "foodability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_NormalViewAbility",
+ "value": "entry_NormalViewAbility"
+ },
+ {
+ "name": "normalviewability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "normalviewability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_ScienceAbility",
+ "value": "entry_ScienceAbility"
+ },
+ {
+ "name": "scienceability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "scienceability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_StoryAbility",
+ "value": "entry_StoryAbility"
+ },
+ {
+ "name": "storyability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "storyability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_WebAbility",
+ "value": "entry_WebAbility"
+ },
+ {
+ "name": "webability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "webability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_TestAbility",
+ "value": "entry_TestAbility"
+ },
+ {
+ "name": "testability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "testability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_CoordinateAbility",
+ "value": "entry_CoordinateAbility"
+ },
+ {
+ "name": "coordinateability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "coordinateability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_PhotoAbility",
+ "value": "entry_PhotoAbility"
+ },
+ {
+ "name": "photoability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "photoability_HelloWorld",
+ "value": "Hello World"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/entry/src/main/resources/zh/element/string.json b/entry/src/main/resources/zh/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..2c1581c9533aa77b9c81b5da90a69dd5e957565c
--- /dev/null
+++ b/entry/src/main/resources/zh/element/string.json
@@ -0,0 +1,124 @@
+{
+ "string": [
+ {
+ "name": "entry_MainAbility",
+ "value": "entry_MainAbility"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "mainability_HelloWorld",
+ "value": "你好,世界"
+ },
+ {
+ "name": "entry_MusicListViewFixedHeaderAbility",
+ "value": "entry_MusicListViewFixedHeaderAbility"
+ },
+ {
+ "name": "musiclistviewfixedheaderability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "musiclistviewfixedheaderability_HelloWorld",
+ "value": "你好,世界"
+ },
+ {
+ "name": "entry_FoodAbility",
+ "value": "entry_FoodAbility"
+ },
+ {
+ "name": "foodability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "foodability_HelloWorld",
+ "value": "你好,世界"
+ },
+ {
+ "name": "entry_NormalViewAbility",
+ "value": "entry_NormalViewAbility"
+ },
+ {
+ "name": "normalviewability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "normalviewability_HelloWorld",
+ "value": "你好,世界"
+ },
+ {
+ "name": "entry_ScienceAbility",
+ "value": "entry_ScienceAbility"
+ },
+ {
+ "name": "scienceability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "scienceability_HelloWorld",
+ "value": "你好,世界"
+ },
+ {
+ "name": "entry_StoryAbility",
+ "value": "entry_StoryAbility"
+ },
+ {
+ "name": "storyability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "storyability_HelloWorld",
+ "value": "你好,世界"
+ },
+ {
+ "name": "entry_WebAbility",
+ "value": "entry_WebAbility"
+ },
+ {
+ "name": "webability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "webability_HelloWorld",
+ "value": "你好,世界"
+ },
+ {
+ "name": "entry_TestAbility",
+ "value": "entry_TestAbility"
+ },
+ {
+ "name": "testability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "testability_HelloWorld",
+ "value": "你好,世界"
+ },
+ {
+ "name": "entry_CoordinateAbility",
+ "value": "entry_CoordinateAbility"
+ },
+ {
+ "name": "coordinateability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "coordinateability_HelloWorld",
+ "value": "你好,世界"
+ },
+ {
+ "name": "entry_PhotoAbility",
+ "value": "entry_PhotoAbility"
+ },
+ {
+ "name": "photoability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "photoability_HelloWorld",
+ "value": "你好,世界"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/entry/src/ohosTest/java/com/lcodecore/twinklingrefreshlayout/ExampleOhosTest.java b/entry/src/ohosTest/java/com/lcodecore/twinklingrefreshlayout/ExampleOhosTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..500eedcf80439841a8087cdfeea13487b14ed54d
--- /dev/null
+++ b/entry/src/ohosTest/java/com/lcodecore/twinklingrefreshlayout/ExampleOhosTest.java
@@ -0,0 +1,14 @@
+package com.lcodecore.twinklingrefreshlayout;
+
+import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ExampleOhosTest {
+ @Test
+ public void testBundleName() {
+ final String actualBundleName = AbilityDelegatorRegistry.getArguments().getTestBundleName();
+ assertEquals("com.lcodecore.twinklingrefreshlayout", actualBundleName);
+ }
+}
\ No newline at end of file
diff --git a/entry/src/test/java/com/lcodecore/twinklingrefreshlayout/ExampleTest.java b/entry/src/test/java/com/lcodecore/twinklingrefreshlayout/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..996ac963c967757a7a46ac9dc9ebd2fb0255cdcc
--- /dev/null
+++ b/entry/src/test/java/com/lcodecore/twinklingrefreshlayout/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.lcodecore.twinklingrefreshlayout;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/art/gif_recyclerview2.gif b/gif/TwinklingRefreshLayout.gif
similarity index 44%
rename from art/gif_recyclerview2.gif
rename to gif/TwinklingRefreshLayout.gif
index bab9ce40895e95e1189179597fa6c458072b19e6..82d1ef1946c543f7cc789231e9aa633824c2ba1f 100644
Binary files a/art/gif_recyclerview2.gif and b/gif/TwinklingRefreshLayout.gif differ
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..be492496f9a20ac2d980ef4fc30061f4184c1c40
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,13 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# If the Chinese output is garbled, please configure the following parameter.
+# This function is enabled by default when the DevEco Studio builds the hap/app,if you need disable gradle parallel,you should set org.gradle.parallel false.
+# more information see https://docs.gradle.org/current/userguide/performance.html
+# org.gradle.parallel=false
+# org.gradle.jvmargs=-Dfile.encoding=GBK
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..f59159e865d4b59feb1b8c44b001f62fc5d58df4
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-6.3-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# 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
+#
+# https://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.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/introduction.md b/introduction.md
deleted file mode 100644
index 396b4f2a668d85ff001307f607fbc9b2ac310480..0000000000000000000000000000000000000000
--- a/introduction.md
+++ /dev/null
@@ -1,413 +0,0 @@
----
-date: 2016-10-11 10:00
-status: public
-title: '想要亲手实现一个刷新控件,你只需要掌握这些知识'
----
-
-十一期间,大家都去玩耍了,笔者以前写的一个开源库收到了star,笔者非常高兴,心血来潮之下,决定重新搞一搞,耗费了三天的假期。笔者期望,这个刷新控件能像Google的SwipeRefreshLayout一样,支持大多数列表控件,另外还得有加载更多功能,最好要很方便的支持个性化吧。开源库在这,[TwinklingRefreshLayout](https://github.com/lcodecorex/TwinklingRefreshLayout),如果喜欢请star,笔者的文章也是围绕着这个控件的实现来说的。
-
-为了方便,笔者将TwinklingRefreshLayout直接继承自FrameLayout而不是ViewGroup,可以省去onMeasure、onLayout等一些麻烦,Header和Footer则是通过LayoutParams来设置View的Gravity属性来做的。
-
-## 1. View的onAttachedToWindow()方法
-首先View没有明显的生命周期,我们又不能再构造函数里面addView()给控件添加头部和底部,因此这个操作比较合适的时机就是在onDraw()之前——onAttachedToWindow()方法中。
-
-此时View被添加到了窗体上,View有了一个用于显示的Surface,将开始绘制。因此其保证了在onDraw()之前调用,但可能在调用 onDraw(Canvas) 之前的任何时刻,包括调用 onMeasure(int, int) 之前或之后。
-比较适合去执行一些初始化操作。(此外在屏蔽Home键的时候也会回调这个方法)
-
-- onDetachedFromWindow()与onAttachedToWindow()方法相对应。
-- ViewGroup先是调用自己的onAttachedToWindow()方法,再调用其每个child的onAttachedToWindow()方法,这样此方法就在整个view树中遍布开了,而visibility并不会对这个方法产生影响。
-
-- onAttachedToWindow方法是在Activity resume的时候被调用的,也就是act对应的window被添加的时候,且每个view只会被调用一次,父view的调用在前,不论view的visibility状态都会被调用,适合做些view特定的初始化操作;
-- onDetachedFromWindow方法是在Activity destroy的时候被调用的,也就是act对应的window被删除的时候,且每个view只会被调用一次,父view的调用在后,也不论view的visibility状态都会被调用,适合做最后的清理操作;
-
-就TwinklingRefreshLayout来说,Header和Footer需要及时显示出来,View又没有明显的生命周期,因此在onAttachedToWindow()中进行设置可以保证在onDraw()之前添加了刷新控件。
-```java
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
-
- //添加头部
- FrameLayout headViewLayout = new FrameLayout(getContext());
- LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
- layoutParams.gravity = Gravity.TOP;
- headViewLayout.setLayoutParams(layoutParams);
-
- mHeadLayout = headViewLayout;
- this.addView(mHeadLayout);//addView(view,-1)添加到-1的位置
-
- //添加底部
- FrameLayout bottomViewLayout = new FrameLayout(getContext());
- LayoutParams layoutParams2 = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
- layoutParams2.gravity = Gravity.BOTTOM;
- bottomViewLayout.setLayoutParams(layoutParams2);
-
- mBottomLayout = bottomViewLayout;
- this.addView(mBottomLayout);
- //...其它步骤
- }
-```
-
-但是当TwinklingRefreshLayout应用在Activity或Fragment中时,可能会因为执行onResume重新触发了onAttachedToWindow()方法而导致重复创建Header和Footer挡住原先添加的View,因此需要加上判断:
-```java
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- System.out.println("onAttachedToWindow绑定窗口");
-
- //添加头部
- if (mHeadLayout == null) {
- FrameLayout headViewLayout = new FrameLayout(getContext());
- LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
- layoutParams.gravity = Gravity.TOP;
- headViewLayout.setLayoutParams(layoutParams);
-
- mHeadLayout = headViewLayout;
-
- this.addView(mHeadLayout);//addView(view,-1)添加到-1的位置
-
- if (mHeadView == null) setHeaderView(new RoundDotView(getContext()));
- }
- //...
- }
-```
-
-## 2. View的事件分发机制
-事件的分发过程由dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent三个方法来共同完成的。由于事件的传递是自顶向下的,对于ViewGroup,笔者觉得最重要的就是onInterceptTouchEvent方法了,它关系到事件是否能够继续向下传递。看如下伪代码:
-```java
-public boolean dispatchTouchEvent(MotionEvenet ev){
- boolean consume = false;
- if (onInterceptTouchEvent(ev)) {
- consume = onTouchEvent(ev);
- }else{
- consume = child.dispatchTouchEvent(ev);
- }
- return consume;
-}
-```
-
-如代码所示,如果ViewGroup拦截了(onInterceptTouchEvent返回true)事件,则事件会在ViewGroup的onTouchEvent方法中消费,而不会传到子View;否则事件将交给子View去分发。
-
-我们需要做的就是在子View滚动到顶部或者底部时及时的拦截事件,让ViewGroup的onTouchEvent来交接处理滑动事件。
-
-## 3. 判断子View滚动达到边界
-在什么时候对事件进行拦截呢?对于Header,当手指向下滑动也就是 dy>0 且子View已经滚动到顶部(不能再向上滚动)时拦截;对于bottom则是 dy<0 且子View已经滚动到底部(不能再向下滚动)时拦截:
-```java
-@Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mTouchY = ev.getY();
- break;
- case MotionEvent.ACTION_MOVE:
- float dy = ev.getY() - mTouchY;
-
- if (dy > 0 && !canChildScrollUp()) {
- state = PULL_DOWN_REFRESH;
- return true;
- } else if (dy < 0 && !canChildScrollDown() && enableLoadmore) {
- state = PULL_UP_LOAD;
- return true;
- }
- break;
- }
- return super.onInterceptTouchEvent(ev);
- }
-```
-
-判断View能不能继续向上滚动,对于sdk14以上版本,v4包里提供了方法:
-```java
-public boolean canChildScrollUp() {
- return ViewCompat.canScrollVertically(mChildView, -1);
-}
-```
-
-其它情况,直接交给子View了,ViewGroup这里也管不着。
-
-## 4. ViewGroup 的 onTouchEvent 方法
-走到这一步,子View的滚动已经交给子View自己去搞了,ViewGroup需要处理的事件只有两个临界状态,也就是用户在下拉可能想要刷新的状态和用户在上拉可能想要加载更多的状态。也就是上面state记录的状态。接下来的事情就简单咯,监听一下ACTION_MOVE和ACTION_UP就好了。
-
-首先在ACTION_DOWN时需要记录下最原先的手指按下的位置 mTouchY,然后在一系列ACTION_MOVE过程中,获取当前位移(ev.getY()-mTouchY),然后通过 **某种计算方式** 不断计算当前的子View应该位移的距离offsetY,调用`mChildView.setTranslationY(offsetY)`来不断设置子View的位移,同时需要给HeadLayout申请布局高度来完成顶部控件的显示。这其中笔者使用的计算方式就是插值器(Interpolator)。
-
-在ACTION_UP时,需要判断子View的位移有没有达到进入刷新或者是加载更多状态的要求,即`mChildView.getTranslationY() >= mHeadHeight - mTouchSlop`,mTouchSlop是为了防止发生抖动而存在。判断进入了刷新状态时,当前子View的位移在HeadHeight和maxHeadHeight之间,所以需要让子View的位移回到HeadHeight处,否则就直接回到0处。
-
-## 5. Interpolator插值器
-Interpolator用于动画中的时间插值,其作用就是把0到1的浮点值变化映射到另一个浮点值变化。上面提到的计算方式如下:
-```java
-float offsetY = decelerateInterpolator.getInterpolation(dy / mWaveHeight / 2) * dy / 2;
-```
-
-其中(dy / mWaveHeight / 2)是一个0~1之间的浮点值,随着下拉高度的增加,这个值越来越大,通过decelerateInterpolator获取到的插值也越来越大,只不过这些值的变化量是越来越小(decelerate效果)。Interpolator继承自TimeInterpolator接口,源码如下:
-```java
-public interface TimeInterpolator {
- /**
- * Maps a value representing the elapsed fraction of an animation to a value that represents
- * the interpolated fraction. This interpolated value is then multiplied by the change in
- * value of an animation to derive the animated value at the current elapsed animation time.
- *
- * @param input A value between 0 and 1.0 indicating our current point
- * in the animation where 0 represents the start and 1.0 represents
- * the end
- * @return The interpolation value. This value can be more than 1.0 for
- * interpolators which overshoot their targets, or less than 0 for
- * interpolators that undershoot their targets.
- */
- float getInterpolation(float input);
-}
-```
-
-getInterpolation接收一个0.0~1.0之间的float参数,0.0代表动画的开始,1.0代表动画的结束。返回值则可以超过1.0,也可以小于0.0,比如OvershotInterpolator。所以getInterpolation()是用来实现输入0~1返回0~1左右的函数值的一个函数。
-
-
-## 6. 属性动画
-上面说到了手指抬起的时候,mChildView的位移要么回到mHeadHeight处,要么回到0处。直接setTranslationY()不免太不友好,所以我们这里使用属性动画来做。本来是直接可以用mChildView.animate()方法来完成属性动画的,因为需要兼容低版本并回调一些参数,所以这里使用ObjectAnimator:
-```java
-private void animChildView(float endValue, long duration) {
- ObjectAnimator oa = ObjectAnimator.ofFloat(mChildView, "translationY", mChildView.getTranslationY(), endValue);
- oa.setDuration(duration);
- oa.setInterpolator(new DecelerateInterpolator());//设置速率为递减
- oa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- int height = (int) mChildView.getTranslationY();//获得mChildView当前y的位置
- height = Math.abs(height);
-
- mHeadLayout.getLayoutParams().height = height;
- mHeadLayout.requestLayout();
- }
- });
- oa.start();
-}
-```
-
-传统的补间动画只能够实现移动、缩放、旋转和淡入淡出这四种动画操作,而且它只是改变了View的显示效果,改变了画布绘制出来的样子,而不会真正去改变View的属性。比如用补间动画对一个按钮进行了移动,只有在原位置点击按钮才会发生响应,而属性动画则可以真正的移动按钮。属性动画最简单的一种使用方式就是使用ValueAnimator:
-```java
-ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
-anim.start();
-```
-
-它可以传入多个参数,如`ValueAnimator.ofFloat(0f, 5f, 3f, 10f)`,他会根据设置的插值器依次计算,比如想做一个心跳的效果,用ValueAnimator来控制心的当前缩放值大小就是个不错的选择。除此之外,还可以调用setStartDelay()方法来设置动画延迟播放的时间,调用setRepeatCount()和setRepeatMode()方法来设置动画循环播放的次数以及循环播放的模式等。
-
-如果想要实现View的位移,ValueAnimator显然是比较麻烦的,我们可以使用ValueAnimator的子类ObjectAnimator,如下:
-```java
-ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
-animator.setDuration(5000);
-animator.start();
-```
-
-传入的第一个值是Object,不局限于View,传入的第二个参数为Object的一个属性,比如传入`"abc"`,ObjectAnimator会去Object里面找有没有 **getAbc()** 和 **setAbc(...)** 这两个方法,如果没有,动画就没有效果,它内部应该是处理了相应的异常。另外还可以用AnimatorSet来实现多个属性动画同时播放,也可以在xml中写属性动画。
-
-## 7. 个性化Header和Footer的接口
-要实现个性化的Header和Footer,最最重要的当然是把滑动过程中系数都回调出来啦。在ACTION_MOVE的时候,在ACTION_UP的时候,还有在mChildView在执行属性动画的时候,而且mChildView当前所处的状态都是很明确的,写个接口就好了。
-```
-public interface IHeaderView {
- View getView();
-
- void onPullingDown(float fraction,float maxHeadHeight,float headHeight);
-
- void onPullReleasing(float fraction,float maxHeadHeight,float headHeight);
-
- void startAnim(float maxHeadHeight,float headHeight);
-
- void onFinish();
-}
-```
-
-getView()方法保证在TwinklingRefreshLayout中可以取到在外部设置的View,onPullingDown()是下拉过程中ACTION_MOVE时的回调方法,onPullReleasing()是下拉状态中ACTION_UP时的回调方法,startAnim()则是正在刷新时回调的方法。其中 **fraction=mChildView.getTranslationY()/mHeadHeight**,fraction=1 时,mChildView的位移恰好是HeadLayout的高度,fraction>1 时则超过了HeadLayout的高度,其最大高度可以到达 **mWaveHeight/mHeadHeight**。这样我们只需要写一个View来实现这个接口就可以实现个性化了,该有的参数都有了!
-
-## 8. 实现越界回弹
-不能在手指快速滚动到顶部时对越界做出反馈,这是一个继承及ViewGroup的刷新控件的通病。没有继承自具体的列表控件,它没办法获取到列表控件的Scroller,不能获取到列表控件的当前滚动速度,更是不能预知列表控件什么时候能滚动到顶部;同时ViewGroup除了达到临界状态的事件被拦截了,其它事件全都交给了子View去处理。我们能获取到的有关于子View的操作,只有简简单单的手指的触摸事件。so, let's do it!
-```java
-mChildView.setOnTouchListener(new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- return gestureDetector.onTouchEvent(event);
- }
-});
-```
-
-我们把在mChildView上的触摸事件交给了一个工具类GestureDetector去处理,它可以辅助检测用户的单击、滑动、长按、双击、快速滑动等行为。我们这里只需要重写onFling()方法并获取到手指在Y方向上的速度velocityY,要是再能及时的发现mChildView滚动到了顶部就可以解决问题了。
-```java
-GestureDetector gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
-
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- mVelocityY = velocityY;
- }
- });
-```
-
-此外获取速度还可以用VelocityTracker,比较麻烦一些:
-```java
-VelocityTracker tracker = VelocityTracker.obtain();
-tracker.addMovement(ev);
-//然后在恰当的位置使用如下方法获取速度
-tracker.computeCurrentVelocity(1000);
-mVelocityY = (int)tracker.getYVelocity();
-```
-
-继续来实现越界回弹。对于RecyclerView、AbsListView,它们提供有OnScrollListener可以获取一下滚动状态:
-```java
-if (mChildView instanceof RecyclerView) {
- ((RecyclerView) mChildView).addOnScrollListener(new RecyclerView.OnScrollListener() {
- @Override
- public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
- if (!isRefreshing && !isLoadingmore && newState == RecyclerView.SCROLL_STATE_IDLE) {
- if (mVelocityY >= 5000 && ScrollingUtil.isRecyclerViewToTop((RecyclerView) mChildView)) {
- animOverScrollTop();
- }
- if (mVelocityY <= -5000 && ScrollingUtil.isRecyclerViewToBottom((RecyclerView) mChildView)) {
- animOverScrollBottom();
- }
- }
- super.onScrollStateChanged(recyclerView, newState);
- }
- });
- }
-```
-
-笔者选取了一个滚动速度的临界值,Y方向的滚动速度大于5000时才允许越界回弹,RecyclerView的OnScrollListener可以让我们获取到滚动状态的改变,滚动到顶部时滚动完成,状态变为SCROLL_STATE_IDLE,执行越界回弹动画。这样的策略也还有一些缺陷,不能获取到mChildView滚动到顶部时的滚动速度,也就不能根据不同的滚动速度来实现更加友好的越界效果。现在的越界高度是固定的,还需要后面进行优化,比如采用加速度来计算,是否可行还待验证。
-
-## 9. 滚动的延时计算策略
-上面的方法对于RecyclerView和AbsListView都好用,对于ScrollView、WebView就头疼了,只能使用延时计算一段时间看有没有到达顶部的方式来判断的策略。延时策略的思想就是通过发送一系列的延时消息从而达到一种渐进式计算的效果,具体来说可以使用Handler或View的postDelayed方法,也可以使用线程的sleep方法。另外提一点,需要不断循环计算一个数值,比如自定义View需要实现根据某个数值变化的动效,最好不要使用Thread + while 循环的方式计算,使用ValueAnimator会是更好的选择。这里笔者选择了Handler的方式。
-```java
-@Override
-public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- mVelocityY = velocityY;
- if (!(mChildView instanceof AbsListView || mChildView instanceof RecyclerView)) {
- //既不是AbsListView也不是RecyclerView,由于这些没有实现OnScrollListener接口,无法回调状态,只能采用延时策略
- if (Math.abs(mVelocityY) >= 5000) {
- mHandler.sendEmptyMessage(MSG_START_COMPUTE_SCROLL);
- } else {
- cur_delay_times = ALL_DELAY_TIMES;
- }
- }
- return false;
-}
-```
-
-在滚动速度大于5000的时候发送一个重新计算的消息,Handler收到消息后,延时一段时间继续给自己发送消息,直到时间用完或者mChildView滚动到顶部或者用户又进行了一次Fling动作。
-```java
-private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_START_COMPUTE_SCROLL:
- cur_delay_times = -1; //这里没有break,写作-1方便计数
- case MSG_CONTINUE_COMPUTE_SCROLL:
- cur_delay_times++;
-
- if (!isRefreshing && !isLoadingmore && mVelocityY >= 5000 && childScrollToTop()) {
- animOverScrollTop();
- cur_delay_times = ALL_DELAY_TIMES;
- }
-
- if (!isRefreshing && !isLoadingmore && mVelocityY <= -5000 && childScrollToBottom()) {
- animOverScrollBottom();
- cur_delay_times = ALL_DELAY_TIMES;
- }
-
- if (cur_delay_times < ALL_DELAY_TIMES)
- mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_COMPUTE_SCROLL, 10);
- break;
- case MSG_STOP_COMPUTE_SCROLL:
- cur_delay_times = ALL_DELAY_TIMES;
- break;
- }
- }
-};
-```
-
-ALL_DELAY_TIMES是最多可以计算的次数,当Handler接收到MSG_START_COMPUTE_SCROLL消息时,如果mChildView没有滚动到边界处,则会在10ms之后向自己发送一条MSG_CONTINUE_COMPUTE_SCROLL的消息,然后继续进行判断。然后在合适的时候越界回弹就好了。
-
-## 10. 实现个性化Header
-这里笔者来演示一下,怎么轻轻松松的做一个个性化的Header,比如新浪微博样式的刷新Header(如下面第1图)。
-
-1. 创建 SinaRefreshView 继承自 FrameLayout 并实现 IHeaderView 接口
-
-2. getView()方法中返回this
-
-3. 在onAttachedToWindow()方法中获取一下需要用到的布局(笔者写到了xml中,也可以直接在代码里面写)
-
-```java
-@Override
-protected void onAttachedToWindow() {
- super.onAttachedToWindow();
-
- if (rootView == null) {
- rootView = View.inflate(getContext(), R.layout.view_sinaheader, null);
- refreshArrow = (ImageView) rootView.findViewById(R.id.iv_arrow);
- refreshTextView = (TextView) rootView.findViewById(R.id.tv);
- loadingView = (ImageView) rootView.findViewById(R.id.iv_loading);
- addView(rootView);
- }
-}
-```
-
-4.实现其它方法
-```java
-@Override
-public void onPullingDown(float fraction, float maxHeadHeight, float headHeight) {
- if (fraction < 1f) refreshTextView.setText(pullDownStr);
- if (fraction > 1f) refreshTextView.setText(releaseRefreshStr);
- refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180);
-}
-
-@Override
-public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) {
- if (fraction < 1f) {
- refreshTextView.setText(pullDownStr);
- refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180);
- if (refreshArrow.getVisibility() == GONE) {
- refreshArrow.setVisibility(VISIBLE);
- loadingView.setVisibility(GONE);
- }
- }
-}
-
-@Override
-public void startAnim(float maxHeadHeight, float headHeight) {
- refreshTextView.setText(refreshingStr);
- refreshArrow.setVisibility(GONE);
- loadingView.setVisibility(VISIBLE);
-}
-```
-
-5.布局文件
-
-```xml
-
-
-
-
-
-
-
-
-```
-
-注意fraction的使用,比如上面的代码 **refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180)**,`fraction * headHeight`表示当前头部滑动的距离,然后算出它和最大高度的比例,然后乘以180,可以使得在滑动到最大距离时Arrow恰好能旋转180度。startAnim()方法是在onRefresh之后会自动调用的方法。
-
-要想实现如图2所示效果,可以具体查看笔者的开源库[TwinklingRefreshLayout](https://github.com/lcodecorex/TwinklingRefreshLayout)。
-
- 
-
-## 总结
-至此,笔者实现这个刷新控件的所有核心思想都讲完了,其中并没有用到多么高深的技术,只是需要我们多一点耐心,多去调试,不要逃避bug,多挑战一下自己。
diff --git a/library/build.gradle b/library/build.gradle
index 3ff351a754fd5a8b2998eb0f214b102ba8635581..7e1e475c1296e7c6d200a45810598ddff583ee7f 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -1,38 +1,21 @@
-apply plugin: 'com.android.library'
-apply plugin: 'com.novoda.bintray-release'
-
-publish{
- userOrg = 'lcodecorex'
- groupId = 'com.lcodecorex'
- artifactId = 'tkrefreshlayout'
- publishVersion = '1.0.7'
- website = 'https://github.com/lcodecorex/TwinklingRefreshLayout/'
-}
-
-android {
- compileSdkVersion 25
- buildToolsVersion '25.0.1'
-
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 6
defaultConfig {
- minSdkVersion 14
- targetSdkVersion 25
- versionCode 7
- versionName "1.07"
+ compatibleSdkVersion 5
}
buildTypes {
release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
}
}
-
- lintOptions {
- abortOnError false
- }
+
}
dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
- compile 'com.android.support:recyclerview-v7:25.2.0'
- compile 'com.android.support:support-v4:25.2.0'
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testImplementation 'junit:junit:4.13'
}
diff --git a/library/consumer-rules.pro b/library/consumer-rules.pro
new file mode 100644
index 0000000000000000000000000000000000000000..9dccc613bc71b04b83531f550bdab2fb667ecfc9
--- /dev/null
+++ b/library/consumer-rules.pro
@@ -0,0 +1 @@
+# Add har specific ProGuard rules for consumer here.
\ No newline at end of file
diff --git a/library/proguard-rules.pro b/library/proguard-rules.pro
index aaf9d0a0a103563d2430a854fa6719ef034f5046..f7666e47561d514b2a76d5a7dfbb43ede86da92a 100644
--- a/library/proguard-rules.pro
+++ b/library/proguard-rules.pro
@@ -1,17 +1 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /Users/lcodecore/Documents/android_sdk_macosx/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
+# config module specific ProGuard rules here.
\ No newline at end of file
diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml
deleted file mode 100644
index 275011b54fe363c438303f63c4f3db3d1102bbeb..0000000000000000000000000000000000000000
--- a/library/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
diff --git a/library/src/main/config.json b/library/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..b08203545b1022289529ebce04f23d4b5f4d68a9
--- /dev/null
+++ b/library/src/main/config.json
@@ -0,0 +1,23 @@
+{
+ "app": {
+ "bundleName": "com.lcodecore.twinklingrefreshlayout",
+ "vendor": "lcodecore",
+ "version": {
+ "code": 1000000,
+ "name": "1.0.0"
+ }
+ },
+ "deviceConfig": {
+ },
+ "module": {
+ "package": "com.lcodecore.tkrefreshlayout",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "library",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/ArrowRefreshHeader.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/ArrowRefreshHeader.java
new file mode 100644
index 0000000000000000000000000000000000000000..4f6f277b10918bd6e0a32a0dd2232658793dec6c
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/ArrowRefreshHeader.java
@@ -0,0 +1,457 @@
+package com.lcodecore.tkrefreshlayout;
+
+
+import com.lcodecore.tkrefreshlayout.processor.AVLoadingIndicatorView;
+import com.lcodecore.tkrefreshlayout.processor.loading.LoadingView;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.Text;
+import ohos.agp.components.element.FrameAnimationElement;
+import ohos.agp.utils.Color;
+import ohos.agp.utils.TextAlignment;
+import ohos.app.Context;
+import ohos.data.DatabaseHelper;
+import ohos.data.preferences.Preferences;
+
+import java.util.Date;
+
+public class ArrowRefreshHeader extends DirectionalLayout implements BaseRefreshHeader {
+ private static final String XR_REFRESH_KEY = "XR_REFRESH_KEY";
+ private static final String XR_REFRESH_TIME_KEY = "XR_REFRESH_TIME_KEY";
+ private static final int ROTATE_ANIM_DURATION = 180;
+ private LoadingView loadingView;
+ private FrameAnimationElement frameAnimationElement;
+ private DirectionalLayout componentContainer;
+ private AVLoadingIndicatorView progressView;
+ private SimpleViewSwitcher mProgressBar;
+ private DirectionalLayout mContainer;
+ private DirectionalLayout mHeaderRefreshTimeContainer;
+ private DirectionalLayout cricle_refresh;
+ private DirectionalLayout listview_header_text;
+ private Image mArrowImageView;
+ private Text mStatusTextView;
+
+ private int mState = STATE_NORMAL;
+ public int mMeasuredHeight;
+ private String customRefreshPsKey = null;
+ private Image image,image1,image2,image3,image4;
+
+ public void destroy() {
+ mProgressBar = null;
+ if (progressView != null) {
+ progressView.destroy();
+ progressView = null;
+ }
+ }
+
+ public ArrowRefreshHeader(Context context) {
+ this(context, null, null);
+ }
+
+ public ArrowRefreshHeader(Context context, AttrSet attrSet) {
+ this(context, attrSet, null);
+ }
+
+ public ArrowRefreshHeader(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ initView(context, attrSet, styleName);
+ }
+
+ public void setRefreshTimeVisible(boolean show) {
+ if (mHeaderRefreshTimeContainer != null)
+ mHeaderRefreshTimeContainer.setVisibility(show ? VISIBLE : HIDE);
+ }
+
+ public void setXrRefreshTimeKey(String keyName) {
+ if (keyName != null) {
+ customRefreshPsKey = keyName;
+ }
+ }
+
+ private void initView(Context context, AttrSet attrSet, String styleName) {
+ headView(context);
+ }
+
+ private DirectionalLayout head_top;
+ public AnimatorProperty animatorProperty1;
+ private AnimatorProperty getValueAnimator(int delay,Image imageView) {
+ animatorProperty1 = imageView.createAnimatorProperty();
+ animatorProperty1.scaleXFrom(0.3f).scaleYFrom(0.3f).scaleXBy(0.7f).scaleYBy(0.7f)
+ .setLoopedCount(1000).setDelay(delay).setDuration(700);
+ animatorProperty1.start();
+ return animatorProperty1;
+ }
+ public AnimatorProperty animatorProperty2;
+ private AnimatorProperty getValueAnimator2(int delay,Image imageView) {
+ animatorProperty2 = imageView.createAnimatorProperty();
+ animatorProperty2.scaleXFrom(0.3f).scaleYFrom(0.3f).scaleXBy(0.7f).scaleYBy(0.7f)
+ .setLoopedCount(1000).setDelay(delay).setDuration(700);
+ animatorProperty2.start();
+ return animatorProperty2;
+ }
+
+ public AnimatorProperty animatorProperty3;
+ private AnimatorProperty getValueAnimator3(int delay,Image imageView) {
+ animatorProperty3 = imageView.createAnimatorProperty();
+ animatorProperty3.scaleXFrom(0.3f).scaleYFrom(0.3f).scaleXBy(0.7f).scaleYBy(0.7f)
+ .setLoopedCount(1000).setDelay(delay).setDuration(700);
+ animatorProperty3.start();
+ return animatorProperty3;
+ }
+ public AnimatorProperty animatorProperty4;
+ private AnimatorProperty getValueAnimator4(int delay,Image imageView) {
+ animatorProperty4 = imageView.createAnimatorProperty();
+ animatorProperty4.scaleXFrom(0.3f).scaleYFrom(0.3f).scaleXBy(0.7f).scaleYBy(0.7f)
+ .setLoopedCount(1000).setDelay(delay).setDuration(700);
+ animatorProperty4.start();
+ return animatorProperty4;
+ }
+
+ public AnimatorProperty animatorProperty5;
+ private AnimatorProperty getValueAnimator5(int delay,Image imageView) {
+ animatorProperty5 = imageView.createAnimatorProperty();
+ animatorProperty5.scaleXFrom(0.3f).scaleYFrom(0.3f).scaleXBy(0.7f).scaleYBy(0.7f)
+ .setLoopedCount(1000).setDelay(delay).setDuration(700);
+ animatorProperty5.start();
+ return animatorProperty5;
+ }
+
+ public void headView(Context context){
+ LayoutScatter scatter = LayoutScatter.getInstance(context);
+ mContainer = (DirectionalLayout) scatter.parse(ResourceTable.Layout_listview_header, null, false);
+
+ listview_header_text = (DirectionalLayout) mContainer.findComponentById(ResourceTable.Id_listview_header_text); // 功能3 箭头和提示刷新
+ cricle_refresh = (DirectionalLayout) mContainer.findComponentById(ResourceTable.Id_cricle_refresh); // 功能1 圆圈刷新
+ mHeaderRefreshTimeContainer = (DirectionalLayout) mContainer.findComponentById(ResourceTable.Id_header_refresh_time_container);
+ DirectionalLayout.LayoutConfig lp = new DirectionalLayout.LayoutConfig(DirectionalLayout.LayoutConfig.MATCH_PARENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT);
+ lp.setMargins(0, 0, 0, 0);
+ this.setPadding(0, 0, 0, 0);
+ this.setLayoutConfig(lp);
+
+ addComponent(mContainer, new DirectionalLayout.LayoutConfig(DirectionalLayout.LayoutConfig.MATCH_PARENT, 0));
+ setAlignment(TextAlignment.BOTTOM);
+
+ frameAnimationElement = new FrameAnimationElement(context, ResourceTable.Graphic_anim_loading_view);
+ componentContainer = (DirectionalLayout) findComponentById(ResourceTable.Id_frame_container);
+ mArrowImageView = (Image) mContainer.findComponentById(ResourceTable.Id_listview_header_arrow);
+ mStatusTextView = (Text) mContainer.findComponentById(ResourceTable.Id_refresh_status_textview);
+
+ head_top = (DirectionalLayout) mContainer.findComponentById(ResourceTable.Id_head_top);// 头部五个圆动画
+ if (XRecyclerView.getStateInfo() == 5) {
+ head_top.setScaleX(0.3f);
+ head_top.setScaleY(0.3f);
+ }
+
+ if (XRecyclerView.getStateInfo() == 3) { // 功能3的刷新
+ listview_header_text.setVisibility(VISIBLE);
+ mArrowImageView.setVisibility(VISIBLE);
+ cricle_refresh.setVisibility(HIDE);
+ } else if(XRecyclerView.getStateInfo() == 1) {
+ cricle_refresh.setVisibility(VISIBLE);
+ listview_header_text.setVisibility(HIDE);
+ } else if(XRecyclerView.getStateInfo() == 5) {
+ cricle_refresh.setVisibility(HIDE);
+ listview_header_text.setVisibility(HIDE);
+ head_top.setVisibility(VISIBLE);
+ }
+ //init the progress view
+ mProgressBar = (SimpleViewSwitcher) mContainer.findComponentById(ResourceTable.Id_listview_header_progressbar);
+ progressView = new AVLoadingIndicatorView(context);
+ progressView.setIndicatorColor(0xffB5B5B5);
+ progressView.setIndicatorId(ProgressStyle.BallSpinFadeLoader);
+ if (mProgressBar != null) {
+ mProgressBar.setView(progressView);
+ progressView.applyAnimation();
+ }
+ estimateSize(ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
+ mMeasuredHeight = getEstimatedHeight();
+
+ image = (Image) mContainer.findComponentById(ResourceTable.Id_image);
+ image1 = (Image) mContainer.findComponentById(ResourceTable.Id_image1);
+ image2 = (Image) mContainer.findComponentById(ResourceTable.Id_image2);
+ image3 = (Image) mContainer.findComponentById(ResourceTable.Id_image3);
+ image4 = (Image) mContainer.findComponentById(ResourceTable.Id_image4);
+ image.setScaleX(0.7f);
+ image.setScaleY(0.7f);
+ image1.setScaleX(0.7f);
+ image1.setScaleY(0.7f);
+ image2.setScaleX(0.7f);
+ image2.setScaleY(0.7f);
+ image3.setScaleX(0.7f);
+ image3.setScaleY(0.7f);
+ image4.setScaleX(0.7f);
+ image4.setScaleY(0.7f);
+
+ loadingView = (LoadingView)
+ mContainer.findComponentById(ResourceTable.Id_progress_bar_loading);
+ loadingView.setBindStateChangedListener(loadingView);
+ loadingView.setPaintcolor(0xff000000);
+ loadingView.setSize(45);
+ loadingView.stopAnimation();
+ }
+ public void setProgressStyle(int style) {
+ if (XRecyclerView.getStateInfo() == 5) { // 功能5的刷新
+ }else {
+ progressView = new AVLoadingIndicatorView(getContext());
+ if (style == ProgressStyle.SysProgress) {
+ progressView.setIndicatorColor(Color.RED.getValue());
+ } else {
+ progressView.setIndicatorColor(0xffB5B5B5);
+ }
+ progressView.setIndicatorId(style);
+ mProgressBar.setView(progressView);
+ progressView.applyAnimation();
+ }
+ }
+
+ public void setIndicatorColor(int color) {
+ progressView.setIndicatorColor(color);
+ this.invalidate();
+ }
+
+ public void setArrowImageView(int resid) {
+ mArrowImageView.setPixelMap(resid);
+ }
+
+ public void setState(int state) {
+ if (state == mState) {
+ return;
+ }
+ if (state == STATE_REFRESHING) {// 显示进度
+ if (XRecyclerView.getStateInfo() == 5) { // 功能5的刷新
+ head_top.setVisibility(VISIBLE);
+ }else{
+ mArrowImageView.setVisibility(VISIBLE);
+ if (mProgressBar != null) {
+ mProgressBar.setVisibility(VISIBLE);
+ }
+ }
+ smoothScrollTo(mMeasuredHeight);
+ } else if (state == STATE_DONE) {
+ if (XRecyclerView.getStateInfo() == 5) { // 功能5的刷新
+ head_top.setScaleX(0.3f);
+ head_top.setScaleY(0.3f);
+ head_top.setVisibility(HIDE);
+ }else {
+ mArrowImageView.setVisibility(HIDE);
+ if (mProgressBar != null) {
+ mProgressBar.setVisibility(INVISIBLE);
+ }
+ }
+ }
+ switch (state) {
+ case STATE_NORMAL:
+ if (XRecyclerView.getStateInfo() == 5) { // 功能5的刷新
+ head_top.setVisibility(VISIBLE);
+ }else {
+ if (XRecyclerView.getStateInfo() == 3) { // 功能3的刷新
+ listview_header_text.setVisibility(VISIBLE);
+ cricle_refresh.setVisibility(HIDE);
+ componentContainer.setVisibility(VISIBLE);
+ mArrowImageView.setVisibility(VISIBLE);
+ } else if (XRecyclerView.getStateInfo() == 1) {
+ mArrowImageView.setVisibility(HIDE);
+ listview_header_text.setVisibility(HIDE);
+ cricle_refresh.setVisibility(VISIBLE);
+ }
+
+ mArrowImageView.setRotation(0);
+ mStatusTextView.setText("下拉刷新");
+ }
+ break;
+ case STATE_RELEASE_TO_REFRESH:
+ if (XRecyclerView.getStateInfo() == 5) { // 功能5的刷新
+ head_top.setVisibility(VISIBLE);
+ }else {
+ if (XRecyclerView.getStateInfo() == 3) { // 功能3的刷新
+ mArrowImageView.setVisibility(VISIBLE);
+
+ } else if (XRecyclerView.getStateInfo() == 1) {
+ loadingView.stopAnimation();
+ }
+ if (mState != STATE_RELEASE_TO_REFRESH) {
+ mArrowImageView.setRotation(180);
+ mStatusTextView.setText("释放刷新");
+ }
+ }
+ break;
+ case STATE_REFRESHING:
+ if (XRecyclerView.getStateInfo() == 5) { // 功能5的刷新
+ head_top.setVisibility(VISIBLE);
+ }else {
+ if (XRecyclerView.getStateInfo() == 3) { // 功能3的刷新
+ listview_header_text.setVisibility(VISIBLE);
+ cricle_refresh.setVisibility(HIDE);
+ componentContainer.setVisibility(VISIBLE);
+ mArrowImageView.setVisibility(HIDE);
+ Component component = new Component(getContext());
+ component.setWidth(80);
+ component.setHeight(80);
+ component.setMarginBottom(10);
+ component.setBackground(frameAnimationElement);
+ componentContainer.addComponent(component);
+ frameAnimationElement.start();
+ } else if (XRecyclerView.getStateInfo() == 1) {
+ mArrowImageView.setVisibility(HIDE);
+ listview_header_text.setVisibility(HIDE);
+ cricle_refresh.setVisibility(VISIBLE);
+ loadingView.startAnimation();
+ }
+
+ mStatusTextView.setText("正在刷新");
+ }
+ break;
+ case STATE_DONE:
+ if (XRecyclerView.getStateInfo() == 5) { // 功能5的刷新
+ head_top.setVisibility(HIDE);
+ if(null != animatorProperty1){
+ animatorProperty1.stop();
+ animatorProperty2.stop();
+ animatorProperty3.stop();
+ animatorProperty4.stop();
+ animatorProperty5.stop();
+
+ image.setScaleX(0.7f);
+ image.setScaleY(0.7f);
+ image1.setScaleX(0.7f);
+ image1.setScaleY(0.7f);
+ image2.setScaleX(0.7f);
+ image2.setScaleY(0.7f);
+ image3.setScaleX(0.7f);
+ image3.setScaleY(0.7f);
+ image4.setScaleX(0.7f);
+ image4.setScaleY(0.7f);
+ }
+ }else {
+ frameAnimationElement.stop();
+ componentContainer.removeAllComponents();
+ mStatusTextView.setText("刷新完成");
+ }
+ break;
+ default:
+ break;
+ }
+ mState = state;
+ }
+
+ public int getState() {
+ return mState;
+ }
+
+ private long getLastRefreshTime() {
+ String spKeyName = XR_REFRESH_KEY;
+ if (customRefreshPsKey != null) {
+ spKeyName = customRefreshPsKey;
+ }
+ DatabaseHelper databaseHelper = new DatabaseHelper(getContext());
+ Preferences preferences = databaseHelper.getPreferences(spKeyName);
+ return preferences.getLong(XR_REFRESH_TIME_KEY, new Date().getTime());
+
+ }
+
+ private void saveLastRefreshTime(long refreshTime) {
+ String spKeyName = XR_REFRESH_KEY;
+ if (customRefreshPsKey != null) {
+ spKeyName = customRefreshPsKey;
+ }
+ DatabaseHelper databaseHelper = new DatabaseHelper(getContext());
+ Preferences preferences = databaseHelper.getPreferences(spKeyName);
+ preferences.putLong(XR_REFRESH_TIME_KEY, refreshTime).flush();
+ }
+
+ @Override
+ public void refreshComplete() {
+ saveLastRefreshTime(System.currentTimeMillis());
+ setState(STATE_DONE);
+ reset();
+ }
+
+ public void setVisibleHeight(int height) {
+ if (height <= 0) {
+ height = 0;
+ } else if (height > 400) {
+ height = 400;
+ }
+ DirectionalLayout.LayoutConfig lp = (DirectionalLayout.LayoutConfig) mContainer.getLayoutConfig();
+ lp.height = height;
+ mContainer.setLayoutConfig(lp);
+ }
+
+ public int getVisibleHeight() {
+ DirectionalLayout.LayoutConfig lp = (DirectionalLayout.LayoutConfig) mContainer.getLayoutConfig();
+ return lp.height;
+ }
+
+ public void setAnimation() {
+ AnimatorProperty animatorProperty = head_top.createAnimatorProperty();
+ animatorProperty.setDuration(200).setDelay(100).scaleX(0.88f).scaleY(0.88f);
+ animatorProperty.start();
+ getValueAnimator(200,image);
+ getValueAnimator2(600,image1);
+ getValueAnimator3(900,image2);
+ getValueAnimator4(600,image3);
+ getValueAnimator5(200,image4);
+ }
+
+ @Override
+ public void onMove(float delta) {
+ if (getVisibleHeight() > 0 || delta > 0) {
+ if (XRecyclerView.getStateInfo() == 5) {
+ System.out.println("delta====" + delta);
+ if(delta <= 300) {
+ float scaleSize = delta / 300.0f;
+ head_top.setScaleX(scaleSize);
+ head_top.setScaleY(scaleSize);
+ }
+ }
+ setVisibleHeight((int) delta);
+ if (mState <= STATE_RELEASE_TO_REFRESH) {// 未处于刷新状态,更新箭头
+ if (getVisibleHeight() > mMeasuredHeight) {
+ setState(STATE_RELEASE_TO_REFRESH);
+ } else {
+ setState(STATE_NORMAL);
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean releaseAction() {
+ boolean isOnRefresh = false;
+ int height = getVisibleHeight();
+ if (height == 0) {
+ isOnRefresh = false;
+ }
+
+ if (getVisibleHeight() > mMeasuredHeight && mState < STATE_REFRESHING) {
+ setState(STATE_REFRESHING);
+ isOnRefresh = true;
+ }
+ if (mState != STATE_REFRESHING) {
+ smoothScrollTo(0);
+ }
+
+ if (mState == STATE_REFRESHING) {
+ int destHeight = mMeasuredHeight;
+ setVisibleHeight(destHeight);
+ }
+
+ return isOnRefresh;
+ }
+
+ public void reset() {
+ smoothScrollTo(0);
+ setState(STATE_NORMAL);
+ }
+
+ private void smoothScrollTo(int destHeight) {
+ setVisibleHeight(0);
+ postLayout();
+ invalidate();
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/BaseRefreshHeader.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/BaseRefreshHeader.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c86157460ed199924775838ce8f9c3bb968df2e
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/BaseRefreshHeader.java
@@ -0,0 +1,18 @@
+package com.lcodecore.tkrefreshlayout;
+
+
+interface BaseRefreshHeader {
+
+ int STATE_NORMAL = 0;
+ int STATE_RELEASE_TO_REFRESH = 1;
+ int STATE_REFRESHING = 2;
+ int STATE_DONE = 3;
+ int STATE_UP = 4;
+
+ void onMove(float delta);
+
+ boolean releaseAction();
+
+ void refreshComplete();
+
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/CustomFooterViewCallBack.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/CustomFooterViewCallBack.java
new file mode 100644
index 0000000000000000000000000000000000000000..503aa5471cc5601aeae58a176ccd95417f566259
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/CustomFooterViewCallBack.java
@@ -0,0 +1,11 @@
+package com.lcodecore.tkrefreshlayout;
+
+import ohos.agp.components.Component;
+
+public interface CustomFooterViewCallBack {
+
+ void onLoadingMore(Component yourFooterView);
+ void onLoadMoreComplete(Component yourFooterView);
+ void onSetNoMore(Component yourFooterView, boolean noMore);
+
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/Footer/BallPulseView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/Footer/BallPulseView.java
index da522d608a38c05489688c9a42884ecefad6332a..397f5c2f38a989769e1f5f2c1b827d2de9d78539 100644
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/Footer/BallPulseView.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/Footer/BallPulseView.java
@@ -1,18 +1,16 @@
-package com.lcodecore.tkrefreshlayout.footer;
-
-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.Gravity;
-import android.view.View;
-import android.widget.FrameLayout.LayoutParams;
+package com.lcodecore.tkrefreshlayout.Footer;
import com.lcodecore.tkrefreshlayout.IBottomView;
import com.lcodecore.tkrefreshlayout.utils.DensityUtil;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
import java.util.ArrayList;
import java.util.HashMap;
@@ -22,60 +20,60 @@ import java.util.Map;
* Created by lcodecore on 2017/3/7.
*/
-public class BallPulseView extends View implements IBottomView {
+public class BallPulseView extends Component implements Component.DrawTask, IBottomView {
public static final int DEFAULT_SIZE = 50; //dp
private float circleSpacing;
private float[] scaleFloats = new float[]{1f, 1f, 1f};
- private ArrayList mAnimators;
- private Map mUpdateListeners = new HashMap<>();
+ private ArrayList mAnimators;
+ private Map mUpdateListeners = new HashMap();
private Paint mPaint;
public BallPulseView(Context context) {
this(context, null);
}
- public BallPulseView(Context context, AttributeSet attrs) {
+ public BallPulseView(Context context, AttrSet attrs) {
this(context, attrs, 0);
}
- public BallPulseView(Context context, AttributeSet attrs, int defStyleAttr) {
+ public BallPulseView(Context context, AttrSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
int default_size = DensityUtil.dp2px(context, DEFAULT_SIZE);
- LayoutParams params = new LayoutParams(default_size, default_size, Gravity.CENTER);
- setLayoutParams(params);
+ DirectionalLayout.LayoutConfig params = new DirectionalLayout.LayoutConfig(default_size, default_size);
+ setLayoutConfig(params);
circleSpacing = DensityUtil.dp2px(context, 4);
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
- mPaint.setStyle(Paint.Style.FILL);
+ mPaint.setStyle(Paint.Style.FILL_STYLE);
mPaint.setAntiAlias(true);
}
public void setIndicatorColor(int color) {
- mPaint.setColor(color);
+ mPaint.setColor(new Color(color));
}
private int normalColor = 0xffeeeeee;
private int animatingColor = 0xffe75946;
- public void setNormalColor(@ColorInt int color) {
+ public void setNormalColor(int color) {
normalColor = color;
}
- public void setAnimatingColor(@ColorInt int color) {
+ public void setAnimatingColor(int color) {
animatingColor = color;
}
@Override
- protected void onDraw(Canvas canvas) {
+ public void onDraw(Component component, Canvas canvas) {
float radius = (Math.min(getWidth(), getHeight()) - circleSpacing * 2) / 6;
- float x = getWidth() / 2 - (radius * 2 + circleSpacing);
- float y = getHeight() / 2;
+ float x = getWidth() / 2.0f - (radius * 2 + circleSpacing);
+ float y = getHeight() / 2.0f;
for (int i = 0; i < 3; i++) {
canvas.save();
float translateX = x + (radius * 2) * i + circleSpacing * i;
@@ -86,9 +84,7 @@ public class BallPulseView extends View implements IBottomView {
}
}
- @Override
protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
if (mAnimators != null) for (int i = 0; i < mAnimators.size(); i++) {
mAnimators.get(i).cancel();
}
@@ -100,12 +96,12 @@ public class BallPulseView extends View implements IBottomView {
if (isStarted()) return;
for (int i = 0; i < mAnimators.size(); i++) {
- ValueAnimator animator = mAnimators.get(i);
+ AnimatorValue 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);
+ AnimatorValue.ValueUpdateListener updateListener = mUpdateListeners.get(animator);
if (updateListener != null) {
- animator.addUpdateListener(updateListener);
+ animator.setValueUpdateListener(updateListener);
}
animator.start();
}
@@ -114,9 +110,9 @@ public class BallPulseView extends View implements IBottomView {
public void stopAnim() {
if (mAnimators != null) {
- for (ValueAnimator animator : mAnimators) {
- if (animator != null && animator.isStarted()) {
- animator.removeAllUpdateListeners();
+ for (AnimatorValue animator : mAnimators) {
+ if (animator != null && animator.isRunning()) {
+ animator.release();
animator.end();
}
}
@@ -125,8 +121,8 @@ public class BallPulseView extends View implements IBottomView {
}
private boolean isStarted() {
- for (ValueAnimator animator : mAnimators) {
- return animator.isStarted();
+ for (AnimatorValue animator : mAnimators) {
+ return animator.isRunning();
}
return false;
}
@@ -137,25 +133,18 @@ public class BallPulseView extends View implements IBottomView {
for (int i = 0; i < 3; i++) {
final int index = i;
- ValueAnimator scaleAnim = ValueAnimator.ofFloat(1, 0.3f, 1);
-
+ AnimatorProperty scaleAnim = new AnimatorProperty();
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);
+ scaleAnim.scaleX(0.3f).scaleY(0.3f).scaleX(1f).scaleY(1f);
+ scaleAnim.setLoopedCount(AnimatorValue.INFINITE);
+ scaleAnim.setDelay(delays[i]);
+ scaleFloats[index] = index;
+ postLayout();
}
}
@Override
- public View getView() {
+ public Component getView() {
return this;
}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/Footer/LoadingView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/Footer/LoadingView.java
index 3f3a6e6cabcaa0d78580d24a4ec985ec1d5ff460..dee9fc05dbb4f9cc294da464532c831fc8640c16 100644
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/Footer/LoadingView.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/Footer/LoadingView.java
@@ -1,42 +1,41 @@
-package com.lcodecore.tkrefreshlayout.footer;
-
-import android.content.Context;
-import android.graphics.drawable.AnimationDrawable;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
+package com.lcodecore.tkrefreshlayout.Footer;
import com.lcodecore.tkrefreshlayout.IBottomView;
-import com.lcodecore.tkrefreshlayout.R;
+import com.lcodecore.tkrefreshlayout.ResourceTable;
import com.lcodecore.tkrefreshlayout.utils.DensityUtil;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+import ohos.agp.components.StackLayout;
+import ohos.app.Context;
+
+import static ohos.agp.utils.LayoutAlignment.CENTER;
/**
* Created by lcodecore on 2016/10/3.
*/
-public class LoadingView extends ImageView implements IBottomView {
+public class LoadingView extends Image implements IBottomView {
public LoadingView(Context context) {
this(context, null);
}
- public LoadingView(Context context, AttributeSet attrs) {
+ public LoadingView(Context context, AttrSet attrs) {
this(context, attrs, 0);
}
- public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
+ public LoadingView(Context context, AttrSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr+"");
int size = DensityUtil.dp2px(context,34);
- FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(size,size);
- params.gravity = Gravity.CENTER;
- setLayoutParams(params);
- setImageResource(R.drawable.anim_loading_view);
+ StackLayout.LayoutConfig params = new StackLayout.LayoutConfig(size,size);
+ params.alignment = CENTER;
+ setLayoutConfig(params);
+ setPixelMap(ResourceTable.Graphic_anim_loading_view);
}
@Override
- public View getView() {
+ public Component getView() {
return this;
}
@@ -47,7 +46,6 @@ public class LoadingView extends ImageView implements IBottomView {
@Override
public void startAnim(float maxHeadHeight, float headHeight) {
- ((AnimationDrawable)getDrawable()).start();
}
@Override
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/IBottomView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/IBottomView.java
index 41c019567ace68a52138883a6b3a1add129608fd..9703fe50b4f552dccdd7c3a22fd8b5539cb35c8c 100644
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/IBottomView.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/IBottomView.java
@@ -1,13 +1,13 @@
package com.lcodecore.tkrefreshlayout;
-import android.view.View;
+import ohos.agp.components.Component;
/**
* Created by lcodecore on 2016/10/1.
*/
public interface IBottomView {
- View getView();
+ Component getView();
/**
* 上拉准备加载更多的动作
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/IHeaderView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/IHeaderView.java
index 537fe3700a54b8c6df15d4136eff0bd7ad6cbb6e..0472f8aa1477d318f2be4a60299bd6072085faf9 100644
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/IHeaderView.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/IHeaderView.java
@@ -1,13 +1,13 @@
package com.lcodecore.tkrefreshlayout;
-import android.view.View;
+import ohos.agp.components.Component;
/**
* Created by lcodecore on 2016/10/1.
*/
public interface IHeaderView {
- View getView();
+ Component getView();
/**
* 下拉准备刷新动作
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/LoadingMoreFooter.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/LoadingMoreFooter.java
new file mode 100644
index 0000000000000000000000000000000000000000..c568033b2b4b62f8ec8d4d6784841252cf10b28f
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/LoadingMoreFooter.java
@@ -0,0 +1,204 @@
+package com.lcodecore.tkrefreshlayout;
+
+import com.lcodecore.tkrefreshlayout.processor.AVLoadingIndicatorView;
+import com.lcodecore.tkrefreshlayout.processor.LVCircularZoom;
+import com.lcodecore.tkrefreshlayout.utils.DeviceUtils;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.element.FrameAnimationElement;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
+
+import static ohos.agp.utils.LayoutAlignment.CENTER;
+
+public class LoadingMoreFooter extends DirectionalLayout implements BaseRefreshHeader{
+
+ public final static int STATE_LOADING = 0;
+ public final static int STATE_COMPLETE = 1;
+ public final static int STATE_NOMORE = 2;
+ public LVCircularZoom circularZoom;
+ public DirectionalLayout footer_bottom;
+ private FrameAnimationElement frameAnimationElement;
+ private DirectionalLayout componentContainer;
+ private int type = 0;
+
+ private AVLoadingIndicatorView progressView;
+ private SimpleViewSwitcher progressCon;
+
+ private Component header;
+
+ public LoadingMoreFooter(Context context) {
+ super(context);
+ initView(context, null, null);
+ }
+
+ public LoadingMoreFooter(Context context, AttrSet attrSet) {
+ super(context, attrSet);
+ initView(context, attrSet, null);
+ }
+
+ public LoadingMoreFooter(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ initView(context, attrSet, styleName);
+ }
+
+ private void initView(Context context, AttrSet attrSet, String styleName){
+ setAlignment(CENTER);
+ setOrientation(HORIZONTAL);
+ setComponentSize(LayoutConfig.MATCH_PARENT, DeviceUtils.dp2px(getContext(),120));
+ progressCon = new SimpleViewSwitcher(context);
+ progressCon.setWidth(DeviceUtils.dp2px(getContext(),40));
+ progressCon.setHeight(DeviceUtils.dp2px(getContext(),40));
+ addComponent(progressCon);
+
+ if (XRecyclerView.getStateInfo() == 3) { // 功能3的刷新
+ addHeadFoot(context);
+ } else if(XRecyclerView.getStateInfo() == 1 || XRecyclerView.getStateInfo() == 5){
+ addText(context);
+ }
+ }
+
+ public void setProgressStyle(int style) {
+ progressView = new AVLoadingIndicatorView(getContext());
+ if (style == ProgressStyle.SysProgress) {
+ progressView.setIndicatorColor(Color.RED.getValue());
+ } else {
+ progressView.setIndicatorColor(0xffB5B5B5);
+ }
+ progressView.setIndicatorId(style);
+ progressCon.setView(progressView);
+ progressView.applyAnimation();
+ }
+
+ public void setIndicatorColor(int color){
+ progressView.setIndicatorColor(color);
+ this.invalidate();
+ }
+
+ public int getVisibleHeight(){
+ DirectionalLayout.LayoutConfig lp = (DirectionalLayout.LayoutConfig) header.getLayoutConfig();
+ return lp.height;
+ }
+
+ public void setState(int state) {
+ switch(state) {
+ case STATE_LOADING: // 0
+ progressCon.setVisibility(VISIBLE);
+ this.setVisibility(VISIBLE);
+ if (XRecyclerView.getStateInfo() == 3) { // 功能3的刷新
+ frameAnimationElement.start();
+ } else if(XRecyclerView.getStateInfo() == 1 || XRecyclerView.getStateInfo() == 5){
+ footer_bottom.setVisibility(VISIBLE);
+ circularZoom.startAnim(300);
+ circularZoom.setViewColor(Color.rgb(240, 84, 72));
+ circularZoom.
+ invalidate();
+ }
+
+ break;
+ case STATE_COMPLETE: // 1
+ if (XRecyclerView.getStateInfo() == 3) { // 功能3的刷新
+ frameAnimationElement.stop();
+ } else if(XRecyclerView.getStateInfo() == 1 || XRecyclerView.getStateInfo() == 5){
+// header.setHeight(0);
+// type = 0;
+ footer_bottom.setVisibility(HIDE);
+ circularZoom.stopAnim();
+ }
+
+ progressCon.setVisibility(HIDE);
+ this.setVisibility(HIDE);
+ break;
+ case STATE_NOMORE: // 2
+ if (XRecyclerView.getStateInfo() == 3) { // 功能3的刷新
+ frameAnimationElement.stop();
+ } else if(XRecyclerView.getStateInfo() == 1 || XRecyclerView.getStateInfo() == 5){
+// header.setHeight(0);
+// type = 0;
+ footer_bottom.setVisibility(INVISIBLE);
+ circularZoom.stopAnim();
+ }
+ progressCon.setVisibility(INVISIBLE);
+ this.setVisibility(INVISIBLE);
+ break;
+ }
+ }
+ public void destroy(){
+ progressCon = null;
+ if(progressView != null){
+ progressView.destroy();
+ progressView = null;
+ }
+ }
+
+ private void addHeadFoot(Context context){
+ LayoutScatter scatter = LayoutScatter.getInstance(context);
+ header = scatter.parse(ResourceTable.Layout_bottom_animation2, null, false);
+ frameAnimationElement = new FrameAnimationElement(getContext(), ResourceTable.Graphic_anim_loading_view);
+ componentContainer = (DirectionalLayout) header.findComponentById(ResourceTable.Id_frame_container);
+ LayoutConfig lp = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_CONTENT);
+ lp.setMargins(0, 0, 0, 0);
+ this.setPadding(0, 0, 0, 0);
+ this.setLayoutConfig(lp);
+ addComponent(header);
+
+ Component component = new Component(getContext());
+ component.setWidth(90);
+ component.setHeight(90);
+ component.setBackground(frameAnimationElement);
+ componentContainer.addComponent(component);
+ }
+
+ private void addText(Context context){
+ LayoutScatter scatter = LayoutScatter.getInstance(context);
+ header = scatter.parse(ResourceTable.Layout_bottom_animation, null, false);
+ LayoutConfig lp = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_CONTENT);
+ lp.setMargins(0, 0, 0, 0);
+ this.setPadding(0, 0, 0, 0);
+ this.setLayoutConfig(lp);
+ circularZoom = (LVCircularZoom) header.findComponentById(ResourceTable.Id_circularZoom);
+ footer_bottom = (DirectionalLayout) header.findComponentById(ResourceTable.Id_footer_bottom);
+
+ addComponent(header);
+ }
+
+ @Override
+ public void onMove(float delta) {
+ if (type == 0) {
+ if (getVisibleHeight() > 0 || delta < 0) {
+ setVisibleHeight((int) delta);
+ if (getVisibleHeight() > 1200) {
+ setState(STATE_LOADING);
+ } else {
+ setState(STATE_NORMAL);
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean releaseAction() {
+ header.setHeight(150);
+ type = 1;
+ invalidate();
+ return false;
+ }
+
+ @Override
+ public void refreshComplete() {
+
+ }
+
+ public void setVisibleHeight(int height) {
+ if (height >= 0) {
+ height = 0;
+ } else if (height <= -500) {
+ height = -500;
+ }
+ header.setHeight(-height);
+ System.out.println("lp.height====" + -height);
+ invalidate();
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/OnGestureListener.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/OnGestureListener.java
index c0434d70a016d864cd96a7474979629a86d855a3..c9970b9424072ddf118e41e1990967fa9ba0dde0 100644
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/OnGestureListener.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/OnGestureListener.java
@@ -1,13 +1,13 @@
package com.lcodecore.tkrefreshlayout;
-import android.view.MotionEvent;
+import ohos.multimodalinput.event.TouchEvent;
public interface OnGestureListener {
- void onDown(MotionEvent ev);
+ void onDown(TouchEvent ev);
- void onScroll(MotionEvent downEvent, MotionEvent currentEvent, float distanceX, float distanceY);
+ void onScroll(TouchEvent downEvent, TouchEvent currentEvent, float distanceX, float distanceY);
- void onUp(MotionEvent ev, boolean isFling);
+ void onUp(TouchEvent ev, boolean isFling);
- void onFling(MotionEvent downEvent, MotionEvent upEvent, float velocityX, float velocityY);
+ void onFling(TouchEvent downEvent, TouchEvent upEvent, float velocityX, float velocityY);
}
\ No newline at end of file
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/OnRefreshListener.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/OnRefreshListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..158964821be38667d0dcdce7e5504fc0ee1fbc73
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/OnRefreshListener.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.tkrefreshlayout;
+
+/**
+ * OnRefreshListener
+ *
+ * @since 2021-07-19
+ */
+public interface OnRefreshListener {
+ /**
+ * 动画执行完成回调
+ */
+ void onRefresh();
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/OnScrollListener.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/OnScrollListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..16609467db627f65f193668bd924f759cdc1e844
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/OnScrollListener.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.tkrefreshlayout;
+
+/**
+ * OnScrollListener
+ *
+ * @since 2021-07-19
+ */
+public interface OnScrollListener {
+ /**
+ * 回调
+ *
+ * @param type
+ */
+ void onListener(int type);
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/OnViewListener.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/OnViewListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..77442def848ae5d11bf0da78093b9a3416579523
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/OnViewListener.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.tkrefreshlayout;
+
+/**
+ * OnScrollListener
+ *
+ * @since 2021-07-19
+ */
+public interface OnViewListener {
+ /**
+ * 回调
+ */
+ void onViewListener();
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/ProgressStyle.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/ProgressStyle.java
new file mode 100644
index 0000000000000000000000000000000000000000..b0b9a645b0d46a19acc89bd34f22451f48e063d1
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/ProgressStyle.java
@@ -0,0 +1,34 @@
+package com.lcodecore.tkrefreshlayout;
+
+
+public class ProgressStyle {
+ public static final int SysProgress=-1;
+ public static final int BallPulse=0;
+ public static final int BallGridPulse=1;
+ public static final int BallClipRotate=2;
+ public static final int BallClipRotatePulse=3;
+ public static final int SquareSpin=4;
+ public static final int BallClipRotateMultiple=5;
+ public static final int BallPulseRise=6;
+ public static final int BallRotate=7;
+ public static final int CubeTransition=8;
+ public static final int BallZigZag=9;
+ public static final int BallZigZagDeflect=10;
+ public static final int BallTrianglePath=11;
+ public static final int BallScale=12;
+ public static final int LineScale=13;
+ public static final int LineScaleParty=14;
+ public static final int BallScaleMultiple=15;
+ public static final int BallPulseSync=16;
+ public static final int BallBeat=17;
+ public static final int LineScalePulseOut=18;
+ public static final int LineScalePulseOutRapid=19;
+ public static final int BallScaleRipple=20;
+ public static final int BallScaleRippleMultiple=21;
+ public static final int BallSpinFadeLoader=22;
+ public static final int LineSpinFadeLoader=23;
+ public static final int TriangleSkewSpin=24;
+ public static final int Pacman=25;
+ public static final int BallGridBeat=26;
+ public static final int SemiCircleSpin=27;
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/PullListener.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/PullListener.java
deleted file mode 100644
index b605f85d5007896afc4465209dc63005f147ac87..0000000000000000000000000000000000000000
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/PullListener.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.lcodecore.tkrefreshlayout;
-
-public interface PullListener {
- /**
- * 下拉中
- *
- * @param refreshLayout
- * @param fraction
- */
- void onPullingDown(TwinklingRefreshLayout refreshLayout, float fraction);
-
- /**
- * 上拉
- */
- void onPullingUp(TwinklingRefreshLayout refreshLayout, float fraction);
-
- /**
- * 下拉松开
- *
- * @param refreshLayout
- * @param fraction
- */
- void onPullDownReleasing(TwinklingRefreshLayout refreshLayout, float fraction);
-
- /**
- * 上拉松开
- */
- void onPullUpReleasing(TwinklingRefreshLayout refreshLayout, float fraction);
-
- /**
- * 刷新中。。。
- */
- void onRefresh(TwinklingRefreshLayout refreshLayout);
-
- /**
- * 加载更多中
- */
- void onLoadMore(TwinklingRefreshLayout refreshLayout);
-
- /**
- * 手动调用finishRefresh或者finishLoadmore之后的回调
- */
- void onFinishRefresh();
-
- void onFinishLoadMore();
-
- /**
- * 正在刷新时向上滑动屏幕,刷新被取消
- */
- void onRefreshCanceled();
-
- /**
- * 正在加载更多时向下滑动屏幕,加载更多被取消
- */
- void onLoadmoreCanceled();
- }
\ No newline at end of file
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/RefreshListenerAdapter.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/RefreshListenerAdapter.java
deleted file mode 100644
index 8987d1756059605a139dec5a15150a65476de18e..0000000000000000000000000000000000000000
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/RefreshListenerAdapter.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.lcodecore.tkrefreshlayout;
-
-public abstract class RefreshListenerAdapter implements PullListener {
- @Override
- public void onPullingDown(TwinklingRefreshLayout refreshLayout, float fraction) {
- }
-
- @Override
- public void onPullingUp(TwinklingRefreshLayout refreshLayout, float fraction) {
- }
-
- @Override
- public void onPullDownReleasing(TwinklingRefreshLayout refreshLayout, float fraction) {
- }
-
- @Override
- public void onPullUpReleasing(TwinklingRefreshLayout refreshLayout, float fraction) {
- }
-
- @Override
- public void onRefresh(TwinklingRefreshLayout refreshLayout) {
- }
-
- @Override
- public void onLoadMore(TwinklingRefreshLayout refreshLayout) {
- }
-
- @Override
- public void onFinishRefresh() {
-
- }
-
- @Override
- public void onFinishLoadMore() {
-
- }
-
- @Override
- public void onRefreshCanceled() {
-
- }
-
- @Override
- public void onLoadmoreCanceled() {
-
- }
-}
\ No newline at end of file
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/SimpleViewSwitcher.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/SimpleViewSwitcher.java
new file mode 100644
index 0000000000000000000000000000000000000000..1918e2d1a388aacdd39a1115bcf31ad6ee57052d
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/SimpleViewSwitcher.java
@@ -0,0 +1,61 @@
+package com.lcodecore.tkrefreshlayout;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.app.Context;
+
+public class SimpleViewSwitcher extends ComponentContainer {
+ public SimpleViewSwitcher(Context context) {
+ super(context);
+ init();
+ }
+
+ public SimpleViewSwitcher(Context context, AttrSet attrSet) {
+ super(context, attrSet);
+ init();
+ }
+
+ public SimpleViewSwitcher(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ init();
+ }
+
+ private void init(){
+
+ setEstimateSizeListener(new EstimateSizeListener() {
+ @Override
+ public boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) {
+ int childCount = SimpleViewSwitcher.this.getChildCount();
+ int maxHeight = 0 ;
+ int maxWidth = 0;
+ for(int i = 0; i < childCount ;i++){
+ Component child = SimpleViewSwitcher.this.getComponentAt(i);
+ maxWidth = child.getEstimatedWidth();
+ maxHeight = child.getEstimatedHeight();
+ }
+ setEstimatedSize(maxWidth,maxHeight);
+ return true;
+ }
+ });
+ setLayoutRefreshedListener(new LayoutRefreshedListener() {
+ @Override
+ public void onRefreshed(Component component) {
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final Component child = getComponentAt(i);
+ if (child.getVisibility() != HIDE) {
+ child.arrange(0,0,getWidth() - getLeft(),getHeight() - getTop());
+ }
+ }
+ }
+ });
+ }
+
+ public void setView(Component componet){
+ if(this.getChildCount() != 0){
+ this.removeComponentAt(0);
+ }
+ this.addComponent(componet,0);
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/StickyScrollLinearLayout.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/StickyScrollLinearLayout.java
new file mode 100644
index 0000000000000000000000000000000000000000..adc4e43b510574d48a6416e6fffe1395395709ad
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/StickyScrollLinearLayout.java
@@ -0,0 +1,114 @@
+package com.lcodecore.tkrefreshlayout;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.DirectionalLayout;
+import ohos.app.Context;
+import ohos.multimodalinput.event.TouchEvent;
+
+public class StickyScrollLinearLayout extends DirectionalLayout implements Component.TouchEventListener {
+ private Component mTopView;
+ private Component mTabView;
+ private Component mContentView;
+
+ private float mStartY = -1;
+ private float moveY = -1;
+
+ public StickyScrollLinearLayout(Context context) {
+ this(context, null,null);
+ }
+
+ public StickyScrollLinearLayout(Context context, AttrSet attrSet) {
+ this(context, attrSet,null);
+ }
+
+ public StickyScrollLinearLayout(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ init(context, attrSet, styleName);
+
+ }
+
+ private void init(Context context, AttrSet attrSet, String styleName) {
+ setOrientation(VERTICAL);
+ }
+
+ public interface StickyScrollInitInterface{
+ Component setTopView();
+ Component setTabView();
+ Component setContentView();
+ }
+
+ public void setInitInterface( StickyScrollInitInterface initInterface){
+ if(initInterface == null)
+ throw new NullPointerException("initInterface can not be null!");
+ this.mTopView = initInterface.setTopView();
+ if(this.mTopView != null)
+ getTopViewHeight();
+ this.mTabView = initInterface.setTabView();
+ this.mContentView = initInterface.setContentView();
+ if(this.mContentView == null)
+ return;
+ setTouchEventListener(this);
+ setTotalHeight();
+ postLayout();
+ }
+
+ private void getTopViewHeight(){
+ if(mTopView == null)
+ return;
+ }
+ private void setTotalHeight(){
+ ComponentContainer.LayoutConfig params = mContentView.getLayoutConfig();
+ params.height = getHeight() -mTabView.getHeight();
+ setComponentSize(getWidth(),mTopView.getHeight()+mTabView.getHeight()+mContentView.getHeight());
+ }
+
+ @Override
+ public boolean onTouchEvent(Component component, TouchEvent ev) {
+ switch (ev.getAction()){
+ case TouchEvent.PRIMARY_POINT_DOWN:
+ mStartY =ev.getPointerScreenPosition(0).getY();
+ break;
+ case TouchEvent.POINT_MOVE:
+ moveY =ev.getPointerScreenPosition(0).getY();
+ float deltaY = moveY - mStartY;
+ if(deltaY < 0){//向上滑动
+ if(Math.abs(getTranslationY()) < mTopView.getHeight()){
+ if(Math.abs(deltaY) >= mTopView.getHeight()){
+ setTranslationY(-mTopView.getHeight());
+ }else {
+ setTranslationY(deltaY);
+ }
+ }
+ }else if( deltaY >0){//向下滑动
+ if(getTranslationY() == 0){
+ return false;
+ }
+
+ if(Math.abs(getTranslationY()) == mTopView.getHeight()){
+ if(deltaY >= mTopView.getHeight()){
+ setTranslationY(0);
+ }else {
+ setTranslationY(getTranslationY()+deltaY);
+ }
+ }
+
+ if(Math.abs(getTranslationY()) < mTopView.getHeight()){
+ float distancesY = getTranslationY()+deltaY;
+ if(distancesY >0 ){
+ distancesY =0;
+ }
+ setTranslationY(distancesY);
+ }
+
+ }
+ break;
+ default:
+ break;
+
+ }
+ return false;
+ }
+
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/TwinklingRefreshLayout.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/TwinklingRefreshLayout.java
deleted file mode 100644
index 455166f9d2196c65da34237ebf0f1d92b4f06277..0000000000000000000000000000000000000000
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/TwinklingRefreshLayout.java
+++ /dev/null
@@ -1,1192 +0,0 @@
-package com.lcodecore.tkrefreshlayout;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.support.v4.view.MotionEventCompat;
-import android.support.v4.view.NestedScrollingChild;
-import android.support.v4.view.NestedScrollingChildHelper;
-import android.support.v4.view.ViewCompat;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.widget.FrameLayout;
-import android.widget.RelativeLayout;
-
-import com.lcodecore.tkrefreshlayout.footer.BallPulseView;
-import com.lcodecore.tkrefreshlayout.header.GoogleDotView;
-import com.lcodecore.tkrefreshlayout.processor.AnimProcessor;
-import com.lcodecore.tkrefreshlayout.processor.IDecorator;
-import com.lcodecore.tkrefreshlayout.processor.OverScrollDecorator;
-import com.lcodecore.tkrefreshlayout.processor.RefreshProcessor;
-import com.lcodecore.tkrefreshlayout.utils.DensityUtil;
-
-import java.lang.reflect.Constructor;
-
-import static android.support.v4.widget.ViewDragHelper.INVALID_POINTER;
-
-/**
- * Created by lcodecore on 16/3/2.
- */
-public class TwinklingRefreshLayout extends RelativeLayout implements PullListener, NestedScrollingChild {
-
- //波浪的高度,最大扩展高度
- protected float mMaxHeadHeight;
- protected float mMaxBottomHeight;
-
- //头部的高度
- protected float mHeadHeight;
-
- //允许的越界回弹的高度
- protected float mOverScrollHeight;
-
- //子控件
- private View mChildView;
-
- //头部layout
- protected FrameLayout mHeadLayout;
-
- //整个头部
- private FrameLayout mExtraHeadLayout;
- //附加顶部高度
- private int mExHeadHeight = 0;
-
- private IHeaderView mHeadView;
- private IBottomView mBottomView;
-
- //设置的默认的header/footer class的完整包名+类名
- private static String HEADER_CLASS_NAME = "";
- private static String FOOTER_CLASS_NAME = "";
-
- //底部高度
- private float mBottomHeight;
-
- //底部layout
- private FrameLayout mBottomLayout;
-
-
- //是否刷新视图可见
- protected boolean isRefreshVisible = false;
-
- //是否加载更多视图可见
- protected boolean isLoadingVisible = false;
-
- //是否处于刷新状态(和isRefreshVisible区别为是否开启了enableKeepHeadWhenRefresh)
- protected boolean isRefreshing = false;
- protected boolean isLoadingMore = false;
-
- //是否需要加载更多,默认需要
- protected boolean enableLoadmore = true;
- //是否需要下拉刷新,默认需要
- protected boolean enableRefresh = true;
-
- //是否在越界回弹的时候显示下拉图标
- protected boolean isOverScrollTopShow = true;
- //是否在越界回弹的时候显示上拉图标
- protected boolean isOverScrollBottomShow = true;
-
- //是否隐藏刷新控件,开启越界回弹模式(开启之后刷新控件将隐藏)
- protected boolean isPureScrollModeOn = false;
-
- //是否自动加载更多
- protected boolean autoLoadMore = false;
-
- //是否开启悬浮刷新模式
- protected boolean floatRefresh = false;
-
- //是否允许进入越界回弹模式
- protected boolean enableOverScroll = true;
-
- //是否在刷新或者加载更多后保持状态
- protected boolean enableKeepIView = true;
-
- //是否在越界且处于刷新时直接显示顶部
- protected boolean showRefreshingWhenOverScroll = true;
-
- //是否在越界且处于加载更多时直接显示底部
- protected boolean showLoadingWhenOverScroll = true;
-
- private CoContext cp;
- private final int mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
- //设置手势动作的监听器
- private PullListener pullListener = this;
-
- private final NestedScrollingChildHelper mChildHelper;
-
- public TwinklingRefreshLayout(Context context) {
- this(context, null, 0);
- }
-
- public TwinklingRefreshLayout(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public TwinklingRefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
-
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TwinklingRefreshLayout, defStyleAttr, 0);
- try {
- mMaxHeadHeight = a.getDimensionPixelSize(R.styleable.TwinklingRefreshLayout_tr_max_head_height, (int) DensityUtil.dp2px(context, 120));
- mHeadHeight = a.getDimensionPixelSize(R.styleable.TwinklingRefreshLayout_tr_head_height, (int) DensityUtil.dp2px(context, 80));
- mMaxBottomHeight = a.getDimensionPixelSize(R.styleable.TwinklingRefreshLayout_tr_max_bottom_height, (int) DensityUtil.dp2px(context, 120));
- mBottomHeight = a.getDimensionPixelSize(R.styleable.TwinklingRefreshLayout_tr_bottom_height, (int) DensityUtil.dp2px(context, 60));
- mOverScrollHeight = a.getDimensionPixelSize(R.styleable.TwinklingRefreshLayout_tr_overscroll_height, (int) mHeadHeight);
- enableRefresh = a.getBoolean(R.styleable.TwinklingRefreshLayout_tr_enable_refresh, true);
- enableLoadmore = a.getBoolean(R.styleable.TwinklingRefreshLayout_tr_enable_loadmore, true);
- isPureScrollModeOn = a.getBoolean(R.styleable.TwinklingRefreshLayout_tr_pureScrollMode_on, false);
- isOverScrollTopShow = a.getBoolean(R.styleable.TwinklingRefreshLayout_tr_overscroll_top_show, true);
- isOverScrollBottomShow = a.getBoolean(R.styleable.TwinklingRefreshLayout_tr_overscroll_bottom_show, true);
- enableOverScroll = a.getBoolean(R.styleable.TwinklingRefreshLayout_tr_enable_overscroll, true);
- floatRefresh = a.getBoolean(R.styleable.TwinklingRefreshLayout_tr_floatRefresh, false);
- autoLoadMore = a.getBoolean(R.styleable.TwinklingRefreshLayout_tr_autoLoadMore, false);
- enableKeepIView = a.getBoolean(R.styleable.TwinklingRefreshLayout_tr_enable_keepIView, true);
- showRefreshingWhenOverScroll = a.getBoolean(R.styleable.TwinklingRefreshLayout_tr_showRefreshingWhenOverScroll, true);
- showLoadingWhenOverScroll = a.getBoolean(R.styleable.TwinklingRefreshLayout_tr_showLoadingWhenOverScroll, true);
- } finally {
- a.recycle();
- }
-
- cp = new CoContext();
-
- addHeader();
- addFooter();
-
- setFloatRefresh(floatRefresh);
- setAutoLoadMore(autoLoadMore);
- setEnableRefresh(enableRefresh);
- setEnableLoadmore(enableLoadmore);
-
- mChildHelper = new NestedScrollingChildHelper(this);
- setNestedScrollingEnabled(true);
- }
-
- private void addHeader() {
- FrameLayout headViewLayout = new FrameLayout(getContext());
- LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, 0);
- layoutParams.addRule(ALIGN_PARENT_TOP);
-
- FrameLayout extraHeadLayout = new FrameLayout(getContext());
- extraHeadLayout.setId(R.id.ex_header);
- LayoutParams layoutParams2 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
-
- this.addView(extraHeadLayout, layoutParams2);
- this.addView(headViewLayout, layoutParams);
-
- mExtraHeadLayout = extraHeadLayout;
- mHeadLayout = headViewLayout;
-
- if (mHeadView == null) {
- if (!TextUtils.isEmpty(HEADER_CLASS_NAME)) {
- try {
- Class headClazz = Class.forName(HEADER_CLASS_NAME);
- Constructor ct = headClazz.getDeclaredConstructor(Context.class);
- setHeaderView((IHeaderView) ct.newInstance(getContext()));
- } catch (Exception e) {
- Log.e("TwinklingRefreshLayout:", "setDefaultHeader classname=" + e.getMessage());
- setHeaderView(new GoogleDotView(getContext()));
- }
- } else {
- setHeaderView(new GoogleDotView(getContext()));
- }
- }
- }
-
- private void addFooter() {
- FrameLayout bottomViewLayout = new FrameLayout(getContext());
- LayoutParams layoutParams2 = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
- layoutParams2.addRule(ALIGN_PARENT_BOTTOM);
- bottomViewLayout.setLayoutParams(layoutParams2);
-
- mBottomLayout = bottomViewLayout;
- this.addView(mBottomLayout);
-
- if (mBottomView == null) {
- if (!TextUtils.isEmpty(FOOTER_CLASS_NAME)) {
- try {
- Class clazz = Class.forName(FOOTER_CLASS_NAME);
- Constructor ct = clazz.getDeclaredConstructor(Context.class);
- setBottomView((IBottomView) ct.newInstance(getContext()));
- } catch (Exception e) {
- Log.e("TwinklingRefreshLayout:", "setDefaultFooter classname=" + e.getMessage());
- setBottomView(new BallPulseView(getContext()));
- }
- } else {
- setBottomView(new BallPulseView(getContext()));
- }
- }
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- //获得子控件
- //onAttachedToWindow方法中mChildView始终是第0个child,把header、footer放到构造函数中,mChildView最后被inflate
- mChildView = getChildAt(3);
-
- cp.init();
- decorator = new OverScrollDecorator(cp, new RefreshProcessor(cp));
- initGestureDetector();
- }
-
- private IDecorator decorator;
- private OnGestureListener listener;
-
- private void initGestureDetector() {
- listener = new OnGestureListener() {
- @Override
- public void onDown(MotionEvent ev) {
- decorator.onFingerDown(ev);
- }
-
- @Override
- public void onScroll(MotionEvent downEvent, MotionEvent currentEvent, float distanceX, float distanceY) {
- decorator.onFingerScroll(downEvent, currentEvent, distanceX, distanceY, vx, vy);
- }
-
- @Override
- public void onUp(MotionEvent ev, boolean isFling) {
- decorator.onFingerUp(ev, isFling);
- }
-
- @Override
- public void onFling(MotionEvent downEvent, MotionEvent upEvent, float velocityX, float velocityY) {
- decorator.onFingerFling(downEvent, upEvent, velocityX, velocityY);
- }
- };
- }
-
- //VelocityX,VelocityY
- private float vx, vy;
-
- private VelocityTracker mVelocityTracker;
- private float mLastFocusX;
- private float mLastFocusY;
- private float mDownFocusX;
- private float mDownFocusY;
- private int mMaximumFlingVelocity = ViewConfiguration.getMaximumFlingVelocity();
- private int mMinimumFlingVelocity = ViewConfiguration.getMinimumFlingVelocity();
- private MotionEvent mCurrentDownEvent;
- private boolean mAlwaysInTapRegion;
- private int mTouchSlopSquare = mTouchSlop * mTouchSlop;
-
- private void detectGesture(MotionEvent ev, OnGestureListener listener) {
- final int action = ev.getAction();
-
- if (mVelocityTracker == null) {
- mVelocityTracker = VelocityTracker.obtain();
- }
- mVelocityTracker.addMovement(ev);
-
- final boolean pointerUp =
- (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP;
- final int skipIndex = pointerUp ? ev.getActionIndex() : -1;
-
- // Determine focal point
- float sumX = 0, sumY = 0;
- final int count = ev.getPointerCount();
- for (int i = 0; i < count; i++) {
- if (skipIndex == i) continue;
- sumX += ev.getX(i);
- sumY += ev.getY(i);
- }
- final int div = pointerUp ? count - 1 : count;
- final float focusX = sumX / div;
- final float focusY = sumY / div;
-
- switch (action & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_POINTER_DOWN:
- mDownFocusX = mLastFocusX = focusX;
- mDownFocusY = mLastFocusY = focusY;
- break;
- case MotionEvent.ACTION_POINTER_UP:
- mDownFocusX = mLastFocusX = focusX;
- mDownFocusY = mLastFocusY = focusY;
-
- // Check the dot product of current velocities.
- // If the pointer that left was opposing another velocity vector, clear.
- mVelocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
- final int upIndex = ev.getActionIndex();
- final int id1 = ev.getPointerId(upIndex);
- final float x1 = mVelocityTracker.getXVelocity(id1);
- final float y1 = mVelocityTracker.getYVelocity(id1);
- for (int i = 0; i < count; i++) {
- if (i == upIndex) continue;
-
- final int id2 = ev.getPointerId(i);
- final float x = x1 * mVelocityTracker.getXVelocity(id2);
- final float y = y1 * mVelocityTracker.getYVelocity(id2);
-
- final float dot = x + y;
- if (dot < 0) {
- mVelocityTracker.clear();
- break;
- }
- }
- break;
- case MotionEvent.ACTION_DOWN:
- mDownFocusX = mLastFocusX = focusX;
- mDownFocusY = mLastFocusY = focusY;
- if (mCurrentDownEvent != null) {
- mCurrentDownEvent.recycle();
- }
- mCurrentDownEvent = MotionEvent.obtain(ev);
- mAlwaysInTapRegion = true;
- listener.onDown(ev);
- break;
- case MotionEvent.ACTION_MOVE:
- final float scrollX = mLastFocusX - focusX;
- final float scrollY = mLastFocusY - focusY;
- if (mAlwaysInTapRegion) {
- final int deltaX = (int) (focusX - mDownFocusX);
- final int deltaY = (int) (focusY - mDownFocusY);
- int distance = (deltaX * deltaX) + (deltaY * deltaY);
- if (distance > mTouchSlopSquare) {
- listener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
- mLastFocusX = focusX;
- mLastFocusY = focusY;
- mAlwaysInTapRegion = false;
- }
- } else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) {
- listener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
- mLastFocusX = focusX;
- mLastFocusY = focusY;
- }
- break;
- case MotionEvent.ACTION_UP:
- final int pointerId = ev.getPointerId(0);
- mVelocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
- vy = mVelocityTracker.getYVelocity(pointerId);
- vx = mVelocityTracker.getXVelocity(pointerId);
-
- boolean isFling = false;
- if ((Math.abs(vy) > mMinimumFlingVelocity)
- || (Math.abs(vx) > mMinimumFlingVelocity)) {
- listener.onFling(mCurrentDownEvent, ev, vx, vy);
- isFling = true;
- }
-
- listener.onUp(ev, isFling);
-
- if (mVelocityTracker != null) {
- mVelocityTracker.recycle();
- mVelocityTracker = null;
- }
- break;
- case MotionEvent.ACTION_CANCEL:
- mAlwaysInTapRegion = false;
- if (mVelocityTracker != null) {
- mVelocityTracker.recycle();
- mVelocityTracker = null;
- }
- break;
- }
- }
-
- /************************************* 触摸事件处理 *****************************************/
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- //1.监听fling动作 2.获取手指滚动速度(存在滚动但非fling的状态)3.分发事件
- boolean consume = decorator.dispatchTouchEvent(ev);
- detectGesture(ev, listener);
- detectNestedScroll(ev);
- return consume;
- }
-
- /**
- * 拦截事件
- *
- * @return return true时,ViewGroup的事件有效,执行onTouchEvent事件
- * return false时,事件向下传递,onTouchEvent无效
- */
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- boolean intercept = decorator.interceptTouchEvent(ev);
- return intercept || super.onInterceptTouchEvent(ev);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent e) {
- boolean consume = decorator.dealTouchEvent(e);
- return consume || super.onTouchEvent(e);
- }
-
- private final int[] mScrollOffset = new int[2];
- private final int[] mScrollConsumed = new int[2];
- private final int[] mNestedOffsets = new int[2];
- private int mActivePointerId = INVALID_POINTER;
- private int mLastTouchX;
- private int mLastTouchY;
- private boolean mIsBeingDragged;
-
- private boolean detectNestedScroll(MotionEvent e) {
- final MotionEvent vtev = MotionEvent.obtain(e);
- final int action = MotionEventCompat.getActionMasked(e);
- final int actionIndex = MotionEventCompat.getActionIndex(e);
-
- if (action == MotionEvent.ACTION_DOWN) {
- mNestedOffsets[0] = mNestedOffsets[1] = 0;
- }
- vtev.offsetLocation(mNestedOffsets[0], mNestedOffsets[1]);
-
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- mActivePointerId = e.getPointerId(0);
- mLastTouchX = (int) e.getX();
- mLastTouchY = (int) e.getY();
- startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
- break;
- case MotionEventCompat.ACTION_POINTER_DOWN:
- mActivePointerId = e.getPointerId(actionIndex);
- mLastTouchX = (int) e.getX(actionIndex);
- mLastTouchY = (int) e.getY(actionIndex);
- break;
- case MotionEvent.ACTION_MOVE:
- final int index = e.findPointerIndex(mActivePointerId);
- if (index < 0) {
- Log.e("TwinklingRefreshLayout", "Error processing scroll; pointer index for id " +
- mActivePointerId + " not found. Did any MotionEvents get skipped?");
- return false;
- }
-
- final int x = (int) e.getX(index);
- final int y = (int) e.getY(index);
-
- int dx = mLastTouchX - x;
- int dy = mLastTouchY - y;
-
- if (dispatchNestedPreScroll(dx, dy, mScrollConsumed, mScrollOffset)) {
- dx -= mScrollConsumed[0];
- dy -= mScrollConsumed[1];
- vtev.offsetLocation(mScrollOffset[0], mScrollOffset[1]);
- // Updated the nested offsets
- mNestedOffsets[0] += mScrollOffset[0];
- mNestedOffsets[1] += mScrollOffset[1];
- }
-
- if (!mIsBeingDragged && Math.abs(dy) > mTouchSlop) {
- final ViewParent parent = getParent();
- if (parent != null) {
- parent.requestDisallowInterceptTouchEvent(true);
- }
- mIsBeingDragged = true;
- if (dy > 0) {
- dy -= mTouchSlop;
- } else {
- dy += mTouchSlop;
- }
- }
-
- if (mIsBeingDragged) {
- mLastTouchY = y - mScrollOffset[1];
-
- final int scrolledDeltaY = 0;
- final int unconsumedY = dy - scrolledDeltaY;
- if (dispatchNestedScroll(0, scrolledDeltaY, 0, unconsumedY, mScrollOffset)) {
- mLastTouchX -= mScrollOffset[0];
- mLastTouchY -= mScrollOffset[1];
- vtev.offsetLocation(mScrollOffset[0], mScrollOffset[1]);
- mNestedOffsets[0] += mScrollOffset[0];
- mNestedOffsets[1] += mScrollOffset[1];
- }
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- stopNestedScroll();
- mIsBeingDragged = false;
- mActivePointerId = INVALID_POINTER;
- break;
- }
- vtev.recycle();
- return true;
- }
-
- //NestedScroll
- @Override
- public void setNestedScrollingEnabled(boolean enabled) {
- mChildHelper.setNestedScrollingEnabled(enabled);
- }
-
- @Override
- public boolean isNestedScrollingEnabled() {
- return mChildHelper.isNestedScrollingEnabled();
- }
-
- @Override
- public boolean startNestedScroll(int axes) {
- return mChildHelper.startNestedScroll(axes);
- }
-
- @Override
- public void stopNestedScroll() {
- mChildHelper.stopNestedScroll();
- }
-
- @Override
- public boolean hasNestedScrollingParent() {
- return mChildHelper.hasNestedScrollingParent();
- }
-
- @Override
- public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
- return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
- }
-
- @Override
- public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
- return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
- }
-
- @Override
- public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
- return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
- }
-
- @Override
- public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
- return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
- }
-
- /************************************** 开放api区 *****************************************/
- //设置默认的header class 名
- public static void setDefaultHeader(String className) {
- HEADER_CLASS_NAME = className;
- }
-
- //设置默认的footer class 名
- public static void setDefaultFooter(String className) {
- FOOTER_CLASS_NAME = className;
- }
-
- //主动刷新
- public void startRefresh() {
- cp.startRefresh();
- }
-
- //主动加载跟多
- public void startLoadMore() {
- cp.startLoadMore();
- }
-
- /**
- * 结束刷新
- */
- public void finishRefreshing() {
- cp.finishRefreshing();
- }
-
- /**
- * 结束加载更多
- */
- public void finishLoadmore() {
- cp.finishLoadmore();
- }
-
- /**
- * 手动设置刷新View
- */
- public void setTargetView(View targetView) {
- if (targetView != null) mChildView = targetView;
- }
-
- /**
- * 手动设置RefreshLayout的装饰器
- */
- public void setDecorator(IDecorator decorator1) {
- if (decorator1 != null) decorator = decorator1;
- }
-
- /**
- * 设置头部刷新View
- */
- public void setHeaderView(final IHeaderView headerView) {
- if (headerView != null) {
- mHeadLayout.removeAllViewsInLayout();
- mHeadLayout.addView(headerView.getView());
- mHeadView = headerView;
- }
- }
-
- /**
- * 设置固定在顶部的header
- */
- @Deprecated
- public void addFixedExHeader(final View view) {
- if (view != null && mExtraHeadLayout != null) {
- mExtraHeadLayout.addView(view);
- mExtraHeadLayout.bringToFront();
- if (floatRefresh) mHeadLayout.bringToFront();
- cp.onAddExHead();
- cp.setExHeadFixed();
- }
- }
-
- /**
- * 获取额外附加的头部
- */
- public View getExtraHeaderView() {
- return mExtraHeadLayout;
- }
-
- /**
- * 设置底部View
- */
- public void setBottomView(final IBottomView bottomView) {
- if (bottomView != null) {
- mBottomLayout.removeAllViewsInLayout();
- mBottomLayout.addView(bottomView.getView());
- mBottomView = bottomView;
- }
- }
-
- public void setFloatRefresh(boolean ifOpenFloatRefreshMode) {
- floatRefresh = ifOpenFloatRefreshMode;
- if (!floatRefresh) return;
- post(new Runnable() {
- @Override
- public void run() {
- if (mHeadLayout != null) mHeadLayout.bringToFront();
- }
- });
- }
-
- /**
- * 设置wave的下拉高度
- */
- public void setMaxHeadHeight(float maxHeightDp) {
- this.mMaxHeadHeight = DensityUtil.dp2px(getContext(), maxHeightDp);
- }
-
- /**
- * 设置下拉头的高度
- */
- public void setHeaderHeight(float headHeightDp) {
- this.mHeadHeight = DensityUtil.dp2px(getContext(), headHeightDp);
- }
-
- public void setMaxBottomHeight(float maxBottomHeight) {
- mMaxBottomHeight = DensityUtil.dp2px(getContext(), maxBottomHeight);
- }
-
- /**
- * 设置底部高度
- */
- public void setBottomHeight(float bottomHeightDp) {
- this.mBottomHeight = DensityUtil.dp2px(getContext(), bottomHeightDp);
- }
-
- /**
- * 是否允许加载更多
- */
- public void setEnableLoadmore(boolean enableLoadmore1) {
- enableLoadmore = enableLoadmore1;
- if (mBottomView != null) {
- if (enableLoadmore) mBottomView.getView().setVisibility(VISIBLE);
- else mBottomView.getView().setVisibility(GONE);
- }
- }
-
- /**
- * 是否允许下拉刷新
- */
- public void setEnableRefresh(boolean enableRefresh1) {
- this.enableRefresh = enableRefresh1;
- if (mHeadView != null) {
- if (enableRefresh) mHeadView.getView().setVisibility(VISIBLE);
- else mHeadView.getView().setVisibility(GONE);
- }
- }
-
- /**
- * 是否允许越界时显示头部刷新控件
- */
- public void setOverScrollTopShow(boolean isOverScrollTopShow) {
- this.isOverScrollTopShow = isOverScrollTopShow;
- }
-
- /**
- * 是否允许越界时显示底部刷新控件
- */
- public void setOverScrollBottomShow(boolean isOverScrollBottomShow) {
- this.isOverScrollBottomShow = isOverScrollBottomShow;
- }
-
- /**
- * 是否允许越界时显示刷新控件(setOverScrollTopShow,setOverScrollBottomShow统一设置方法)
- */
- public void setOverScrollRefreshShow(boolean isOverScrollRefreshShow) {
- this.isOverScrollTopShow = isOverScrollRefreshShow;
- this.isOverScrollBottomShow = isOverScrollRefreshShow;
- }
-
- /**
- * 是否允许开启越界回弹模式
- */
- public void setEnableOverScroll(boolean enableOverScroll1) {
- this.enableOverScroll = enableOverScroll1;
- }
-
- /**
- * 是否开启纯净的越界回弹模式,开启时刷新和加载更多控件不显示
- */
- public void setPureScrollModeOn() {
- isPureScrollModeOn = true;
-
- isOverScrollTopShow = false;
- isOverScrollBottomShow = false;
- setMaxHeadHeight(mOverScrollHeight);
- setHeaderHeight(mOverScrollHeight);
- setMaxBottomHeight(mOverScrollHeight);
- setBottomHeight(mOverScrollHeight);
- }
-
- /**
- * 设置越界高度
- */
- public void setOverScrollHeight(float overScrollHeightDp) {
- this.mOverScrollHeight = DensityUtil.dp2px(getContext(), overScrollHeightDp);
- }
-
- /**
- * 设置OverScroll时自动加载更多
- *
- * @param ifAutoLoadMore 为true表示底部越界时主动进入加载跟多模式,否则直接回弹
- */
- public void setAutoLoadMore(boolean ifAutoLoadMore) {
- autoLoadMore = ifAutoLoadMore;
- if (!autoLoadMore) return;
- setEnableLoadmore(true);
- }
-
- public void showRefreshingWhenOverScroll(boolean ifShow) {
- showRefreshingWhenOverScroll = ifShow;
- }
-
- public void showLoadingWhenOverScroll(boolean ifShow) {
- showLoadingWhenOverScroll = ifShow;
- }
-
- public void setEnableKeepIView(boolean ifKeep) {
- enableKeepIView = ifKeep;
- }
-
- /**
- * 设置刷新控件监听器
- */
- private RefreshListenerAdapter refreshListener;
-
- public void setOnRefreshListener(RefreshListenerAdapter refreshListener) {
- if (refreshListener != null) {
- this.refreshListener = refreshListener;
- }
- }
-
- @Override
- public void onPullingDown(TwinklingRefreshLayout refreshLayout, float fraction) {
- mHeadView.onPullingDown(fraction, mMaxHeadHeight, mHeadHeight);
- if (!enableRefresh) return;
- if (refreshListener != null) refreshListener.onPullingDown(refreshLayout, fraction);
- }
-
- @Override
- public void onPullingUp(TwinklingRefreshLayout refreshLayout, float fraction) {
- mBottomView.onPullingUp(fraction, mMaxHeadHeight, mHeadHeight);
- if (!enableLoadmore) return;
- if (refreshListener != null) refreshListener.onPullingUp(refreshLayout, fraction);
- }
-
- @Override
- public void onPullDownReleasing(TwinklingRefreshLayout refreshLayout, float fraction) {
- mHeadView.onPullReleasing(fraction, mMaxHeadHeight, mHeadHeight);
- if (!enableRefresh) return;
- if (refreshListener != null)
- refreshListener.onPullDownReleasing(refreshLayout, fraction);
- }
-
- @Override
- public void onPullUpReleasing(TwinklingRefreshLayout refreshLayout, float fraction) {
- mBottomView.onPullReleasing(fraction, mMaxBottomHeight, mBottomHeight);
- if (!enableLoadmore) return;
- if (refreshListener != null) refreshListener.onPullUpReleasing(refreshLayout, fraction);
- }
-
- @Override
- public void onRefresh(TwinklingRefreshLayout refreshLayout) {
- mHeadView.startAnim(mMaxHeadHeight, mHeadHeight);
- if (refreshListener != null) refreshListener.onRefresh(refreshLayout);
- }
-
- @Override
- public void onLoadMore(TwinklingRefreshLayout refreshLayout) {
- mBottomView.startAnim(mMaxBottomHeight, mBottomHeight);
- if (refreshListener != null) refreshListener.onLoadMore(refreshLayout);
- }
-
- @Override
- public void onFinishRefresh() {
- if (refreshListener != null) {
- refreshListener.onFinishRefresh();
- }
- if (!cp.isEnableKeepIView() && !cp.isRefreshing()) return;
- mHeadView.onFinish(new OnAnimEndListener() {
- @Override
- public void onAnimEnd() {
- cp.finishRefreshAfterAnim();
- }
- });
- }
-
- @Override
- public void onFinishLoadMore() {
- if (refreshListener != null) {
- refreshListener.onFinishLoadMore();
- }
- if (!cp.isEnableKeepIView() && !cp.isLoadingMore()) return;
- mBottomView.onFinish();
- }
-
- @Override
- public void onRefreshCanceled() {
- if (refreshListener != null) refreshListener.onRefreshCanceled();
- }
-
- @Override
- public void onLoadmoreCanceled() {
- if (refreshListener != null) refreshListener.onLoadmoreCanceled();
- }
-
-
- public class CoContext {
- private AnimProcessor animProcessor;
-
- private final static int PULLING_TOP_DOWN = 0;
- private final static int PULLING_BOTTOM_UP = 1;
- private int state = PULLING_TOP_DOWN;
-
- private static final int EX_MODE_NORMAL = 0;
- private static final int EX_MODE_FIXED = 1;
- private int exHeadMode = EX_MODE_NORMAL;
-
- public CoContext() {
- animProcessor = new AnimProcessor(this);
- }
-
- public void init() {
- if (isPureScrollModeOn) {
- setOverScrollTopShow(false);
- setOverScrollBottomShow(false);
- if (mHeadLayout != null) mHeadLayout.setVisibility(GONE);
- if (mBottomLayout != null) mBottomLayout.setVisibility(GONE);
- }
- }
-
- public AnimProcessor getAnimProcessor() {
- return animProcessor;
- }
-
- public boolean isEnableKeepIView() {
- return enableKeepIView;
- }
-
- public boolean showRefreshingWhenOverScroll() {
- return showRefreshingWhenOverScroll;
- }
-
- public boolean showLoadingWhenOverScroll() {
- return showLoadingWhenOverScroll;
- }
-
- public float getMaxHeadHeight() {
- return mMaxHeadHeight;
- }
-
- public int getHeadHeight() {
- return (int) mHeadHeight;
- }
-
- public int getExtraHeadHeight() {
- return mExtraHeadLayout.getHeight();
- }
-
- public int getMaxBottomHeight() {
- return (int) mMaxBottomHeight;
- }
-
- public int getBottomHeight() {
- return (int) mBottomHeight;
- }
-
- public int getOsHeight() {
- return (int) mOverScrollHeight;
- }
-
- public View getTargetView() {
- return mChildView;
- }
-
- public View getHeader() {
- return mHeadLayout;
- }
-
- public View getFooter() {
- return mBottomLayout;
- }
-
- public int getTouchSlop() {
- return mTouchSlop;
- }
-
- public void resetHeaderView() {
- if (mHeadView != null) mHeadView.reset();
- }
-
- public void resetBottomView() {
- if (mBottomView != null) mBottomView.reset();
- }
-
- public View getExHead() {
- return mExtraHeadLayout;
- }
-
- public void setExHeadNormal() {
- exHeadMode = EX_MODE_NORMAL;
- }
-
- public void setExHeadFixed() {
- exHeadMode = EX_MODE_FIXED;
- }
-
- public boolean isExHeadNormal() {
- return exHeadMode == EX_MODE_NORMAL;
- }
-
- public boolean isExHeadFixed() {
- return exHeadMode == EX_MODE_FIXED;
- }
-
- /**
- * 在添加附加Header前锁住,阻止一些额外的位移动画
- */
- private boolean isExHeadLocked = true;
-
- public boolean isExHeadLocked() {
- return isExHeadLocked;
- }
-
- //添加了额外头部时触发
- public void onAddExHead() {
- isExHeadLocked = false;
- LayoutParams params = (LayoutParams) mChildView.getLayoutParams();
- params.addRule(BELOW, mExtraHeadLayout.getId());
- mChildView.setLayoutParams(params);
- requestLayout();
- }
-
-
- /**
- * 主动刷新、加载更多、结束
- */
- public void startRefresh() {
- post(new Runnable() {
- @Override
- public void run() {
- setStatePTD();
- if (!isPureScrollModeOn && mChildView != null) {
- setRefreshing(true);
- animProcessor.animHeadToRefresh();
- }
- }
- });
- }
-
- public void startLoadMore() {
- post(new Runnable() {
- @Override
- public void run() {
- setStatePBU();
- if (!isPureScrollModeOn && mChildView != null) {
- setLoadingMore(true);
- animProcessor.animBottomToLoad();
- }
- }
- });
- }
-
- public void finishRefreshing() {
- onFinishRefresh();
- }
-
- public void finishRefreshAfterAnim() {
- if (mChildView != null) {
- animProcessor.animHeadBack(true);
- }
- }
-
- public void finishLoadmore() {
- onFinishLoadMore();
- if (mChildView != null) {
- animProcessor.animBottomBack(true);
- }
- }
-
- public boolean enableOverScroll() {
- return enableOverScroll;
- }
-
- public boolean allowPullDown() {
- return enableRefresh || enableOverScroll;
- }
-
- public boolean allowPullUp() {
- return enableLoadmore || enableOverScroll;
- }
-
- public boolean enableRefresh() {
- return enableRefresh;
- }
-
- public boolean enableLoadmore() {
- return enableLoadmore;
- }
-
- public boolean allowOverScroll() {
- return (!isRefreshVisible && !isLoadingVisible);
- }
-
- public boolean isRefreshVisible() {
- return isRefreshVisible;
- }
-
- public boolean isLoadingVisible() {
- return isLoadingVisible;
- }
-
- public void setRefreshVisible(boolean visible) {
- isRefreshVisible = visible;
- }
-
- public void setLoadVisible(boolean visible) {
- isLoadingVisible = visible;
- }
-
- public void setRefreshing(boolean refreshing) {
- isRefreshing = refreshing;
- }
-
- public boolean isRefreshing() {
- return isRefreshing;
- }
-
- public boolean isLoadingMore() {
- return isLoadingMore;
- }
-
- public void setLoadingMore(boolean loadingMore) {
- isLoadingMore = loadingMore;
- }
-
- public boolean isOpenFloatRefresh() {
- return floatRefresh;
- }
-
- public boolean autoLoadMore() {
- return autoLoadMore;
- }
-
- public boolean isPureScrollModeOn() {
- return isPureScrollModeOn;
- }
-
- public boolean isOverScrollTopShow() {
- return isOverScrollTopShow;
- }
-
- public boolean isOverScrollBottomShow() {
- return isOverScrollBottomShow;
- }
-
- public void onPullingDown(float offsetY) {
- pullListener.onPullingDown(TwinklingRefreshLayout.this, offsetY / mHeadHeight);
- }
-
- public void onPullingUp(float offsetY) {
- pullListener.onPullingUp(TwinklingRefreshLayout.this, offsetY / mBottomHeight);
- }
-
- public void onRefresh() {
- pullListener.onRefresh(TwinklingRefreshLayout.this);
- }
-
- public void onLoadMore() {
- pullListener.onLoadMore(TwinklingRefreshLayout.this);
- }
-
- public void onFinishRefresh() {
- pullListener.onFinishRefresh();
- }
-
- public void onFinishLoadMore() {
- pullListener.onFinishLoadMore();
- }
-
- public void onPullDownReleasing(float offsetY) {
- pullListener.onPullDownReleasing(TwinklingRefreshLayout.this, offsetY / mHeadHeight);
- }
-
- public void onPullUpReleasing(float offsetY) {
- pullListener.onPullUpReleasing(TwinklingRefreshLayout.this, offsetY / mBottomHeight);
- }
-
- public boolean dispatchTouchEventSuper(MotionEvent ev) {
- return TwinklingRefreshLayout.super.dispatchTouchEvent(ev);
- }
-
- public void onRefreshCanceled() {
- pullListener.onRefreshCanceled();
- }
-
- public void onLoadmoreCanceled() {
- pullListener.onLoadmoreCanceled();
- }
-
- public void setStatePTD() {
- state = PULLING_TOP_DOWN;
- }
-
- public void setStatePBU() {
- state = PULLING_BOTTOM_UP;
- }
-
- public boolean isStatePTD() {
- return PULLING_TOP_DOWN == state;
- }
-
- public boolean isStatePBU() {
- return PULLING_BOTTOM_UP == state;
- }
-
- private boolean prepareFinishRefresh = false;
- private boolean prepareFinishLoadMore = false;
-
- public boolean isPrepareFinishRefresh() {
- return prepareFinishRefresh;
- }
-
- public boolean isPrepareFinishLoadMore() {
- return prepareFinishLoadMore;
- }
-
- public void setPrepareFinishRefresh(boolean prepareFinishRefresh) {
- this.prepareFinishRefresh = prepareFinishRefresh;
- }
-
- public void setPrepareFinishLoadMore(boolean prepareFinishLoadMore) {
- this.prepareFinishLoadMore = prepareFinishLoadMore;
- }
- }
-}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/XRecyclerView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/XRecyclerView.java
new file mode 100644
index 0000000000000000000000000000000000000000..a56889162d65fccb8d920cb5da30f2672097cb4b
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/XRecyclerView.java
@@ -0,0 +1,574 @@
+package com.lcodecore.tkrefreshlayout;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.BaseItemProvider;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.ListContainer;
+import ohos.agp.components.ScrollHelper;
+import ohos.agp.database.DataSetSubscriber;
+import ohos.app.Context;
+import ohos.multimodalinput.event.TouchEvent;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import static ohos.agp.utils.LayoutAlignment.TOP;
+
+public class XRecyclerView extends ListContainer implements Component.LayoutRefreshedListener,
+ Component.TouchEventListener {
+ //下面的ItemViewType是保留值(ReservedItemViewType),如果用户的adapter与它们重复将会强制抛出异常。不过为了简化,我们检测到重复时对用户的提示是ItemViewType必须小于10000
+ private static int stateInfo = -1;
+ private static final int TYPE_REFRESH_HEADER = 10000;//设置一个很大的数字,尽可能避免和用户的adapter冲突
+ private static final int TYPE_FOOTER = 10001;
+ private static final int HEADER_INIT_INDEX = 10002;
+ private static List sHeaderTypes = new ArrayList<>();//每个header必须有不同的type,不然滚动的时候顺序会变化
+ private static ArrayList mHeaderViews = new ArrayList<>();
+
+ private int mRefreshProgressStyle = ProgressStyle.SysProgress;
+ private int mLoadingMoreProgressStyle = ProgressStyle.SysProgress;
+ // limit number to call load more
+ private static int height;
+ private float mLastY = -1;
+ private float dragRate = 3;
+
+ private BaseItemProvider mWrapAdapter;
+ private static ArrowRefreshHeader mRefreshHeader;
+ private static LoadingMoreFooter footView;
+ private LoadingListener mLoadingListener;
+ private ScrollHelper mScrollhelper;
+ private DataSetSubscriber mDataObserver = new DataObserver();
+
+ //adapter没有数据的时候显示,类似于listView的emptyView
+ private Component mEmptyView;
+ private Component mFootView;
+
+ //是否下拉刷新
+ private boolean pullRefreshEnabled = true;
+ private boolean refreshEnabled = false;
+
+ //上拉刷新加载更多数据
+ private static boolean loadingMoreEnabled = true;
+ private static boolean isLoadingData = false;
+ private boolean isNoMore = false;
+
+ public static boolean isLoadingMoreEnabled() {
+ return loadingMoreEnabled;
+ }
+
+ public static void setIsLoadingMoreEnabled(boolean isLoadingMore) {
+ loadingMoreEnabled = isLoadingMore;
+ }
+
+ public static boolean isIsLoadingData() {
+ return isLoadingData;
+ }
+
+ public static void setIsLoadingData(boolean isLoading) {
+ isLoadingData = isLoading;
+ }
+
+ public XRecyclerView(Context context) {
+ super(context);
+ init(context);
+ }
+
+ public XRecyclerView(Context context, AttrSet attrSet) {
+ super(context, attrSet);
+ setStateInfo(attrSet.getAttr("density").get().getIntegerValue());
+ init(context);
+ }
+
+ public XRecyclerView(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ setStateInfo(attrSet.getAttr("density").get().getIntegerValue());
+ init(context);
+ }
+
+ private void init(Context context) {
+ mHeaderViews.clear();
+ mScrollhelper = new ScrollHelper();
+ setTouchEventListener(this);
+ setLayoutRefreshedListener(this);
+ if (pullRefreshEnabled) {
+ mRefreshHeader = new ArrowRefreshHeader(context);
+ mRefreshHeader.setProgressStyle(mRefreshProgressStyle);
+ }
+
+ footView = new LoadingMoreFooter(context);
+ footView.setProgressStyle(mLoadingMoreProgressStyle);
+ mFootView = footView;
+ mFootView.setVisibility(HIDE);
+ }
+
+ public static int getStateInfo() {
+ return stateInfo;
+ }
+
+ public static void setStateInfo(int state) {
+ stateInfo = state;
+ }
+
+ /**
+ * call it when you finish the activity,
+ * when you call this,better don't call some kind of functions like
+ * RefreshHeader,because the reference of mHeaderViews is NULL.
+ */
+ public void destroy() {
+ if (mHeaderViews != null) {
+ mHeaderViews.clear();
+ mHeaderViews = null;
+ }
+ ((LoadingMoreFooter) mFootView).destroy();
+ mFootView = null;
+ if (mRefreshHeader != null) {
+ mRefreshHeader.destroy();
+ mRefreshHeader = null;
+ }
+ }
+
+ public ArrowRefreshHeader getDefaultRefreshHeaderView() {
+ if (mRefreshHeader == null) {
+ return null;
+ }
+ return mRefreshHeader;
+ }
+
+ public LoadingMoreFooter getDefaultFootView() {
+ if (mFootView == null) {
+ return null;
+ }
+ return ((LoadingMoreFooter) mFootView);
+ }
+
+ public void loadMoreComplete() {
+ setIsLoadingData(false);
+ ((LoadingMoreFooter) mFootView).setState(LoadingMoreFooter.STATE_COMPLETE);
+ mFootView.setVisibility(HIDE);
+ footView.invalidate();
+ mFootView.invalidate();
+ mWrapAdapter.notifyDataChanged();
+
+ if (null != onViewListener) {
+ onViewListener.onViewListener();
+ }
+ }
+
+ public void setNoMore(boolean noMore) {
+ setIsLoadingData(false);
+ isNoMore = noMore;
+ ((LoadingMoreFooter) mFootView).setState(isNoMore ? LoadingMoreFooter.STATE_NOMORE : LoadingMoreFooter.STATE_COMPLETE);
+ }
+
+ public void setHeadFootStyle(int state) {
+ setStateInfo(state);
+ }
+
+ public void refresh() {
+ if (pullRefreshEnabled && mLoadingListener != null) {
+ mRefreshHeader.setState(ArrowRefreshHeader.STATE_REFRESHING);
+ mLoadingListener.onRefresh();
+ }
+ }
+
+ public void reset() {
+ loadMoreComplete();
+ refreshComplete();
+ }
+
+ public void refreshComplete() {
+ if (mRefreshHeader != null)
+ mRefreshHeader.refreshComplete();
+ if (mWrapAdapter != null) mWrapAdapter.notifyDataChanged();
+ }
+
+ public void setPullRefreshEnabled(boolean enabled) {
+ pullRefreshEnabled = enabled;
+ }
+
+ public void setLoadingMoreEnabled(boolean enabled) {
+ setIsLoadingMoreEnabled(enabled);
+ if (!enabled) {
+ ((LoadingMoreFooter) mFootView).setState(LoadingMoreFooter.STATE_COMPLETE);
+ }
+ }
+
+ public void setRefreshProgressStyle(int style) {
+ mRefreshProgressStyle = style;
+ if (mRefreshHeader != null) {
+ mRefreshHeader.setProgressStyle(style);
+ }
+ }
+
+ public void setRefreshProgressIndicatorColor(int color) {
+ if (mRefreshHeader != null) {
+ mRefreshHeader.setIndicatorColor(color);
+ }
+ }
+
+ public void setLoadingMoreProgressStyle(int style) {
+ mLoadingMoreProgressStyle = style;
+ ((LoadingMoreFooter) mFootView).setProgressStyle(style);
+ }
+
+ public void setLoadingMoreProgressIndicatorColor(int color) {
+ ((LoadingMoreFooter) mFootView).setIndicatorColor(color);
+ }
+
+ //设置下拉时图图标样式
+ public void setArrowImageView(int resId) {
+ if (mRefreshHeader != null) {
+ mRefreshHeader.setArrowImageView(resId);
+ }
+ }
+
+ // 设置下拉时候的偏移计量因子。y = deltaY/dragRate
+ // dragRate 越大,意味着,用户要下拉滑动更久来触发下拉刷新。相反越小,就越短距离
+ public void setDragRate(float rate) {
+ if (rate <= 0.5) {
+ return;
+ }
+ dragRate = rate;
+ }
+
+ // if you can't sure that you are 100% going to
+ // have no data load back from server anymore,do not use this
+ @Deprecated
+ public void setEmptyView(Component emptyView) {
+ this.mEmptyView = emptyView;
+ mDataObserver.onChanged();
+ }
+
+ @Deprecated
+ public Component getEmptyView() {
+ return mEmptyView;
+ }
+
+ //上拉加载更多数据
+ private void initComputeScroll() {
+ setScrolledListener(new ScrolledListener() {
+ @Override
+ public void onContentScrolled(Component component, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
+ System.out.println("onContentScrolled=" + scrollX + "==" + scrollY + "==" + oldScrollX + "==" + oldScrollY);
+ if (null != onScrollListener) {
+ if (scrollY >= 250 && scrollY <= 380) {
+ onScrollListener.onListener(1);
+ } else if (scrollY <= 100) {
+ onScrollListener.onListener(0);
+ } else if (scrollY <= 10) {
+ onScrollListener.onListener(2);
+ }
+ }
+
+ if (mScrollhelper.isFinished()) {
+ int lastIndex = getLastVisibleItemPosition();
+ int adjLen = isLoadingMoreEnabled() ? 2 : 1;
+ if (mLoadingListener != null && !isIsLoadingData() && isLoadingMoreEnabled() && lastIndex == mWrapAdapter.getCount() - adjLen) {
+ if (footView.getVisibility() == HIDE) {
+ setIsLoadingData(true);
+ ((LoadingMoreFooter) mFootView).setState(LoadingMoreFooter.STATE_LOADING);
+ }
+ if (footView.getVisibility() == VISIBLE) {
+ mLoadingListener.onLoadMore();
+ }
+ }
+ }
+ }
+ });
+ }
+
+ public void setLoadingListener(LoadingListener listener) {
+ mLoadingListener = listener;
+ }
+
+ public interface LoadingListener {
+
+ void onRefresh();
+
+ void onLoadMore();
+ }
+
+ @Override
+ public void setItemProvider(BaseItemProvider itemProvider) {
+ mWrapAdapter = itemProvider;
+ super.setItemProvider(itemProvider);
+ }
+
+ @Override
+ public BaseItemProvider getItemProvider() {
+ return super.getItemProvider();
+ }
+
+ @Override
+ public void onRefreshed(Component component) {
+ initComputeScroll();
+ invalidate();
+ }
+
+ @Override
+ public boolean onTouchEvent(Component component, TouchEvent ev) {
+ int firstIndex = getItemPosByVisibleIndex(0);
+ switch (ev.getAction()) {
+ case TouchEvent.PRIMARY_POINT_DOWN:
+ mLastY = ev.getPointerScreenPosition(0).getY();
+ break;
+ case TouchEvent.POINT_MOVE:
+ if (mRefreshHeader != null && mRefreshHeader.getState() ==
+ ArrowRefreshHeader.STATE_REFRESHING && mRefreshHeader.getVisibleHeight() != 0) {
+ return false;
+ }
+ float deltaY = ev.getPointerScreenPosition(0).getY() - mLastY;
+ if (pullRefreshEnabled && firstIndex <= 1) {
+ refreshEnabled = true;
+ if (mRefreshHeader == null) {
+ break;
+ }
+ mRefreshHeader.onMove(deltaY / dragRate);
+ mWrapAdapter.notifyDataSetItemRangeChanged(1, 2);
+ invalidate();
+ if (mRefreshHeader.getVisibleHeight() > 0 && mRefreshHeader.getState() < ArrowRefreshHeader.STATE_REFRESHING) {
+ return true;
+ }
+ } else {
+ mLastY = ev.getPointerScreenPosition(0).getY();
+ }
+ break;
+ case TouchEvent.CANCEL:
+ case TouchEvent.PRIMARY_POINT_UP:
+ mLastY = -1;
+ if (XRecyclerView.getStateInfo() == 5) { // 抬手缩小功能
+ mRefreshHeader.setAnimation();
+ }
+ if (pullRefreshEnabled && refreshEnabled) {
+ refreshEnabled = false;
+ if (mRefreshHeader != null && mRefreshHeader.releaseAction() && firstIndex == 0) {
+ if (mLoadingListener != null) {
+ mLoadingListener.onRefresh();
+ mWrapAdapter.notifyDataChanged();
+ }
+ } else {
+ mWrapAdapter.notifyDataChanged();
+ }
+ }
+ break;
+
+ }
+ return true;
+ }
+
+ public void addHeaderView(Component view) {
+ if (mHeaderViews == null || sHeaderTypes == null)
+ return;
+ sHeaderTypes.add(HEADER_INIT_INDEX + mHeaderViews.size());
+ mHeaderViews.add(view);
+ if (mWrapAdapter != null) {
+ mWrapAdapter.notifyDataChanged();
+ }
+ }
+
+ public void removeHeaderView(Component v) {
+ if (mHeaderViews == null || sHeaderTypes == null || v == null)
+ return;
+ for (Component view : mHeaderViews) {
+ if (view == v) {
+ mHeaderViews.remove(view);
+ break;
+ }
+ }
+ if (mWrapAdapter != null) {
+ mWrapAdapter.notifyDataChanged();
+ }
+ }
+
+ public void removeAllHeaderView() {
+ if (mHeaderViews == null || sHeaderTypes == null)
+ return;
+ mHeaderViews.clear();
+ if (mWrapAdapter != null) {
+ mWrapAdapter.notifyDataChanged();
+ }
+ }
+
+ /**
+ * ======================================================= ItemProvider start=======================================================
+ */
+ public static abstract class RecyclerAdapter extends BaseItemProvider {
+ private Context context;
+ private List data;
+ private int mLayoutId;
+ private int numColumns = 1;
+ private OnItemClickListener onItemClickListener;
+
+ public RecyclerAdapter(Context context, List data, int mLayoutId) {
+ this.context = context;
+ this.data = data;
+ this.mLayoutId = mLayoutId;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ @Override
+ public int getCount() {
+ int adjLen = (isLoadingMoreEnabled() ? 2 : 1) + mHeaderViews.size();
+ return (data.size() % numColumns == 0 ? data.size() / numColumns : data.size() / numColumns + 1) + adjLen;
+ }
+
+ @Override
+ public T getItem(int position) {
+ return data.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public int getItemComponentType(int position) {
+ if (position == getCount() - 1) {
+ return TYPE_FOOTER;
+ }
+ return super.getItemComponentType(position);
+ }
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer parent) {
+ if (position == 0) {
+ return mRefreshHeader;
+ } else if (position > 0 && position < mHeaderViews.size() + 1) {
+ Component component = mHeaderViews.get(position - 1);
+ return component;
+ } else if (position == getCount() - 1) {
+ return footView;
+ }
+
+ ViewHolder viewHolder;
+ convertComponent = new DirectionalLayout(context);
+ ((DirectionalLayout) convertComponent).setOrientation(Component.HORIZONTAL);
+ LayoutConfig layoutConfig = convertComponent.getLayoutConfig();
+ layoutConfig.width = DirectionalLayout.LayoutConfig.MATCH_PARENT;
+ layoutConfig.height = DirectionalLayout.LayoutConfig.MATCH_CONTENT;
+
+ convertComponent.setLayoutConfig(layoutConfig);
+
+ for (int i = 0; i < numColumns; i++) {
+ if ((position - 1) * numColumns + i < data.size()) {
+ DirectionalLayout dlItemParent = new DirectionalLayout(context);
+ dlItemParent.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, DirectionalLayout.LayoutConfig.MATCH_CONTENT, TOP, 1));
+ height = dlItemParent.getHeight();
+ Component childConvertComponent = LayoutScatter.getInstance(context).parse(mLayoutId, null, false);
+ int finalI = i;
+ childConvertComponent.setClickedListener(new ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ onItemClickListener.onItemClick(component, (position - 1) * numColumns + finalI);
+ }
+ });
+ dlItemParent.addComponent(childConvertComponent);
+ ((ComponentContainer) convertComponent).addComponent(dlItemParent);
+ viewHolder = new ViewHolder(childConvertComponent);
+ bind(viewHolder, getItem((position - 1) * numColumns + i), (position - 1) * numColumns + i);
+ } else {
+ Component childConvertComponent = new Component(context);
+ DirectionalLayout.LayoutConfig layoutConfig1 = new DirectionalLayout.LayoutConfig(0, height);
+ layoutConfig1.weight = 1;
+ childConvertComponent.setLayoutConfig(layoutConfig1);
+ ((ComponentContainer) convertComponent).addComponent(childConvertComponent);
+ }
+ }
+ return convertComponent;
+ }
+
+ public void setNumColumns(int numColumns) {
+ this.numColumns = numColumns;
+ }
+
+ public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
+ this.onItemClickListener = onItemClickListener;
+ }
+
+ public abstract void bind(ViewHolder holder, T s, int position);
+
+ public class ViewHolder {
+ HashMap mViews = new HashMap<>();
+ public Component itemView;
+
+ public ViewHolder(Component component) {
+ this.itemView = component;
+ }
+
+ public E getView(int viewId) {
+ E view = (E) mViews.get(viewId);
+ if (view == null) {
+ view = (E) itemView.findComponentById(viewId);
+ mViews.put(viewId, view);
+ }
+ return view;
+ }
+ }
+
+ public abstract static class OnItemClickListener {
+ public abstract void onItemClick(Component component, int position);
+ }
+
+ }
+
+ /**
+ * ======================================================= ItemProvider end=======================================================
+ */
+ private class DataObserver extends DataSetSubscriber {
+ @Override
+ public void onChanged() {
+ if (mWrapAdapter != null) {
+ mWrapAdapter.notifyDataChanged();
+ }
+ }
+
+ @Override
+ public void onItemChanged(int position) {
+ mWrapAdapter.notifyDataSetItemChanged(position);
+ }
+
+ @Override
+ public void onItemInserted(int position) {
+ mWrapAdapter.notifyDataSetItemInserted(position);
+ }
+
+ @Override
+ public void onItemRemoved(int position) {
+ mWrapAdapter.notifyDataSetItemRemoved(position);
+ }
+
+ @Override
+ public void onItemRangeChanged(int startPos, int countItems) {
+ mWrapAdapter.notifyDataSetItemRangeChanged(startPos, countItems);
+ }
+
+ @Override
+ public void onItemRangeInserted(int startPos, int countItems) {
+ mWrapAdapter.notifyDataSetItemRangeInserted(startPos, countItems);
+ }
+
+ @Override
+ public void onItemRangeRemoved(int startPos, int countItems) {
+ mWrapAdapter.notifyDataSetItemRangeRemoved(startPos, countItems);
+ }
+ }
+
+ private OnScrollListener onScrollListener;
+
+ public void setSListener(OnScrollListener listener) {
+ onScrollListener = listener;
+ }
+
+ private OnViewListener onViewListener;
+
+ public void setViewListener(OnViewListener viewlistener) {
+ onViewListener = viewlistener;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/GoogleDotView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/GoogleDotView.java
deleted file mode 100644
index 7734c82a8452ee3cc6fff1a4f4e9d30ea30f6cf9..0000000000000000000000000000000000000000
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/GoogleDotView.java
+++ /dev/null
@@ -1,227 +0,0 @@
-package com.lcodecore.tkrefreshlayout.header;
-
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.animation.DecelerateInterpolator;
-
-import com.lcodecore.tkrefreshlayout.OnAnimEndListener;
-import com.lcodecore.tkrefreshlayout.R;
-import com.lcodecore.tkrefreshlayout.IHeaderView;
-import com.lcodecore.tkrefreshlayout.utils.DensityUtil;
-
-/**
- * Created by lcodecore on 2016/10/2.
- */
-
-public class GoogleDotView extends View implements IHeaderView {
- private Paint mPath;
- private float r;
- private int num = 5;
-
- public void setCir_x(int cir_x) {
- this.cir_x = cir_x;
- }
-
- private int cir_x;
-
- float fraction1;
- float fraction2;
- boolean animating = false;
-
- public GoogleDotView(Context context) {
- this(context, null, 0);
- }
-
- public GoogleDotView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public GoogleDotView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init();
- }
-
- ValueAnimator animator1, animator2;
-
- private void init() {
- r = DensityUtil.dp2px(getContext(), 4);
-
- mPath = new Paint();
- mPath.setAntiAlias(true);
- mPath.setColor(Color.rgb(114, 114, 114));
-
- animator1 = ValueAnimator.ofFloat(1f, 1.2f, 1f, 0.8f);
- animator1.setDuration(800);
- animator1.setInterpolator(new DecelerateInterpolator());
- animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- fraction1 = (float) animation.getAnimatedValue();
- invalidate();
- }
- });
- animator1.setRepeatCount(ValueAnimator.INFINITE);
- animator1.setRepeatMode(ValueAnimator.REVERSE);
-
- animator2 = ValueAnimator.ofFloat(1f, 0.8f, 1f, 1.2f);
- animator2.setDuration(800);
- animator2.setInterpolator(new DecelerateInterpolator());
- animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- fraction2 = (float) animation.getAnimatedValue();
- }
- });
- animator2.setRepeatCount(ValueAnimator.INFINITE);
- animator2.setRepeatMode(ValueAnimator.REVERSE);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- int w = getMeasuredWidth() / num - 10;
- for (int i = 0; i < num; i++) {
- if (animating) {
- switch (i) {
- // case 0:
- // mPath.setAlpha(35);
- // mPath.setColor(getResources().getColor(R.color.Orange));
- // canvas.drawCircle(getMeasuredWidth() / 2 - cir_x * 3 - 3 * w / 3 * 2, getMeasuredHeight() / 2, r*fraction2, mPath);
- // break;
- case 0:
- mPath.setAlpha(105);
- mPath.setColor(getResources().getColor(R.color.Yellow));
- canvas.drawCircle(getMeasuredWidth() / 2 - cir_x * 2 - 2 * w / 3 * 2, getMeasuredHeight() / 2, r * fraction2, mPath);
- break;
- case 1:
- mPath.setAlpha(145);
- mPath.setColor(getResources().getColor(R.color.Green));
- canvas.drawCircle(getMeasuredWidth() / 2 - cir_x * 1 - w / 3 * 2, getMeasuredHeight() / 2, r * fraction2, mPath);
- break;
- case 2:
- mPath.setAlpha(255);
- mPath.setColor(getResources().getColor(R.color.Blue));
- canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, r * fraction1, mPath);
- break;
- case 3:
- mPath.setAlpha(145);
- mPath.setColor(getResources().getColor(R.color.Orange));
- canvas.drawCircle(getMeasuredWidth() / 2 + cir_x * 1 + w / 3 * 2, getMeasuredHeight() / 2, r * fraction2, mPath);
- break;
- case 4:
- mPath.setAlpha(105);
- mPath.setColor(getResources().getColor(R.color.Yellow));
- canvas.drawCircle(getMeasuredWidth() / 2 + cir_x * 2 + 2 * w / 3 * 2, getMeasuredHeight() / 2, r * fraction2, mPath);
- break;
- // case 6:
- // mPath.setAlpha(35);
- // mPath.setColor(getResources().getColor(R.color.Green));
- // canvas.drawCircle(getMeasuredWidth() / 2 + cir_x * 3 + 3 * w / 3 * 2, getMeasuredHeight() / 2, r*fraction2, mPath);
- // break;
- }
- } else {
- switch (i) {
- // case 0:
- // mPath.setAlpha(35);
- // mPath.setColor(getResources().getColor(R.color.Orange));
- // canvas.drawCircle(getMeasuredWidth() / 2 - cir_x * 3 - 3 * w / 3 * 2, getMeasuredHeight() / 2, r, mPath);
- // break;
- case 0:
- mPath.setAlpha(105);
- mPath.setColor(getResources().getColor(R.color.Yellow));
- canvas.drawCircle(getMeasuredWidth() / 2 - cir_x * 2 - 2 * w / 3 * 2, getMeasuredHeight() / 2, r, mPath);
- break;
- case 1:
- mPath.setAlpha(145);
- mPath.setColor(getResources().getColor(R.color.Green));
- canvas.drawCircle(getMeasuredWidth() / 2 - cir_x * 1 - w / 3 * 2, getMeasuredHeight() / 2, r, mPath);
- break;
- case 2:
- mPath.setAlpha(255);
- mPath.setColor(getResources().getColor(R.color.Blue));
- canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, r, mPath);
- break;
- case 3:
- mPath.setAlpha(145);
- mPath.setColor(getResources().getColor(R.color.Orange));
- canvas.drawCircle(getMeasuredWidth() / 2 + cir_x * 1 + w / 3 * 2, getMeasuredHeight() / 2, r, mPath);
- break;
- case 4:
- mPath.setAlpha(105);
- mPath.setColor(getResources().getColor(R.color.Yellow));
- canvas.drawCircle(getMeasuredWidth() / 2 + cir_x * 2 + 2 * w / 3 * 2, getMeasuredHeight() / 2, r, mPath);
- break;
- // case 6:
- // mPath.setAlpha(35);
- // mPath.setColor(getResources().getColor(R.color.Green));
- // canvas.drawCircle(getMeasuredWidth() / 2 + cir_x * 3 + 3 * w / 3 * 2, getMeasuredHeight() / 2, r, mPath);
- // break;
- }
- }
- }
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- if (animator1 != null) animator1.cancel();
- if (animator2 != null) animator2.cancel();
- }
-
- @Override
- public View getView() {
- return this;
- }
-
- @Override
- public void onPullingDown(float fraction, float maxHeadHeight, float headHeight) {
- setScaleX(1 + fraction / 2);
- setScaleY(1 + fraction / 2);
- animating = false;
- if (animator1.isRunning()) {
- animator1.cancel();
- invalidate();
- }
- if (animator2.isRunning()) animator2.cancel();
- }
-
- @Override
- public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) {
- setScaleX(1 + fraction / 2);
- setScaleY(1 + fraction / 2);
- if (fraction < 1.0f) {
- animating = false;
- if (animator1.isRunning()) {
- animator1.cancel();
- invalidate();
- }
- if (animator2.isRunning()) animator2.cancel();
- }
- }
-
-
- @Override
- public void startAnim(float maxHeadHeight, float headHeight) {
- animating = true;
- animator1.start();
- animator2.start();
- }
-
- @Override
- public void onFinish(OnAnimEndListener listener) {
- listener.onAnimEnd();
- }
-
- @Override
- public void reset() {
- animating = false;
- if (animator1.isRunning()) animator1.cancel();
- if (animator2.isRunning()) animator2.cancel();
- invalidate();
- }
-}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/SinaRefreshView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/SinaRefreshView.java
index 98188138bcf3cb4777e7bd668d6a1a1c99bcc00a..ba65eb5a3a17c0c352599346352dea7781467ae6 100644
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/SinaRefreshView.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/SinaRefreshView.java
@@ -1,56 +1,59 @@
package com.lcodecore.tkrefreshlayout.header;
-import android.content.Context;
-import android.graphics.drawable.AnimationDrawable;
-import android.support.annotation.ColorInt;
-import android.support.annotation.DrawableRes;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.TextView;
-
import com.lcodecore.tkrefreshlayout.IHeaderView;
import com.lcodecore.tkrefreshlayout.OnAnimEndListener;
-import com.lcodecore.tkrefreshlayout.R;
+import com.lcodecore.tkrefreshlayout.ResourceTable;
+import ohos.agp.colors.RgbColor;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.StackLayout;
+import ohos.agp.components.Text;
+import ohos.agp.components.element.ShapeElement;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
/**
* Created by lcodecore on 2016/10/2.
*/
-public class SinaRefreshView extends FrameLayout implements IHeaderView {
+public class SinaRefreshView extends StackLayout implements IHeaderView {
- private ImageView refreshArrow;
- private ImageView loadingView;
- private TextView refreshTextView;
+ private Image refreshArrow;
+ private Image loadingView;
+ private Text refreshTextView;
public SinaRefreshView(Context context) {
this(context, null);
}
- public SinaRefreshView(Context context, AttributeSet attrs) {
+ public SinaRefreshView(Context context, AttrSet attrs) {
this(context, attrs, 0);
}
- public SinaRefreshView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init();
+ public SinaRefreshView(Context context, AttrSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr+"");
+ init(context);
}
- private void init() {
- View rootView = View.inflate(getContext(), R.layout.view_sinaheader, null);
- refreshArrow = (ImageView) rootView.findViewById(R.id.iv_arrow);
- refreshTextView = (TextView) rootView.findViewById(R.id.tv);
- loadingView = (ImageView) rootView.findViewById(R.id.iv_loading);
- addView(rootView);
+ private void init(Context context) {
+ Component rootView = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_view_sinaheader,
+ null, false);
+ refreshArrow = (Image) rootView.findComponentById(ResourceTable.Id_iv_arrow);
+ refreshTextView = (Text) rootView.findComponentById(ResourceTable.Id_tv);
+ loadingView = (Image) rootView.findComponentById(ResourceTable.Id_iv_loading);
+ addComponent(rootView);
}
- public void setArrowResource(@DrawableRes int resId) {
- refreshArrow.setImageResource(resId);
+ public void setArrowResource(int resId) {
+ ShapeElement shapeElement = new ShapeElement();
+ shapeElement.setRgbColor(RgbColor.fromArgbInt(resId));
+ refreshArrow.setImageElement(shapeElement);
}
- public void setTextColor(@ColorInt int color) {
- refreshTextView.setTextColor(color);
+ public void setTextColor(int color) {
+ refreshTextView.setTextColor(new Color(color));
}
public void setPullDownStr(String pullDownStr1) {
@@ -70,7 +73,7 @@ public class SinaRefreshView extends FrameLayout implements IHeaderView {
private String refreshingStr = "正在刷新";
@Override
- public View getView() {
+ public Component getView() {
return this;
}
@@ -86,9 +89,9 @@ public class SinaRefreshView extends FrameLayout implements IHeaderView {
if (fraction < 1f) {
refreshTextView.setText(pullDownStr);
refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180);
- if (refreshArrow.getVisibility() == GONE) {
+ if (refreshArrow.getVisibility() == HIDE) {
refreshArrow.setVisibility(VISIBLE);
- loadingView.setVisibility(GONE);
+ loadingView.setVisibility(HIDE);
}
}
}
@@ -96,9 +99,8 @@ public class SinaRefreshView extends FrameLayout implements IHeaderView {
@Override
public void startAnim(float maxHeadHeight, float headHeight) {
refreshTextView.setText(refreshingStr);
- refreshArrow.setVisibility(GONE);
+ refreshArrow.setVisibility(HIDE);
loadingView.setVisibility(VISIBLE);
- ((AnimationDrawable) loadingView.getDrawable()).start();
}
@Override
@@ -109,7 +111,7 @@ public class SinaRefreshView extends FrameLayout implements IHeaderView {
@Override
public void reset() {
refreshArrow.setVisibility(VISIBLE);
- loadingView.setVisibility(GONE);
+ loadingView.setVisibility(HIDE);
refreshTextView.setText(pullDownStr);
}
}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/BezierLayout.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/BezierLayout.java
index 021c12025d54ce606623d4722ccadbb8b7c9a5a4..8d102267caae898001db1ced04560b42da04f69a 100644
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/BezierLayout.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/BezierLayout.java
@@ -1,45 +1,45 @@
package com.lcodecore.tkrefreshlayout.header.bezierlayout;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.support.annotation.ColorInt;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.FrameLayout;
-
import com.lcodecore.tkrefreshlayout.OnAnimEndListener;
-import com.lcodecore.tkrefreshlayout.R;
import com.lcodecore.tkrefreshlayout.IHeaderView;
+import com.lcodecore.tkrefreshlayout.OnRefreshListener;
+import com.lcodecore.tkrefreshlayout.ResourceTable;
+import com.lcodecore.tkrefreshlayout.utils.AnimatorValueUtil;
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.StackLayout;
+import ohos.app.Context;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
/**
* Created by lcodecore on 2016/10/2.
*/
-public class BezierLayout extends FrameLayout implements IHeaderView {
+public class BezierLayout extends StackLayout implements IHeaderView {
public BezierLayout(Context context) {
this(context, null);
}
- public BezierLayout(Context context, AttributeSet attrs) {
+ public BezierLayout(Context context, AttrSet attrs) {
this(context, attrs, 0);
}
- public BezierLayout(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init(attrs);
+ public BezierLayout(Context context, AttrSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr + "");
+ init(attrs, context);
}
- View headView;
+ Component headView;
WaveView waveView;
RippleView rippleView;
RoundDotView r1;
RoundProgressView r2;
- private void init(AttributeSet attrs) {
+ private void init(AttrSet attrs, Context context) {
/**
* attrs 需要在xml设置什么属性 自己自定义吧 啊哈哈
*/
@@ -47,21 +47,22 @@ public class BezierLayout extends FrameLayout implements IHeaderView {
/**
* 初始化headView
*/
- headView = LayoutInflater.from(getContext()).inflate(R.layout.view_bezier, null);
- waveView = (WaveView) headView.findViewById(R.id.draweeView);
- rippleView = (RippleView) headView.findViewById(R.id.ripple);
- r1 = (RoundDotView) headView.findViewById(R.id.round1);
- r2 = (RoundProgressView) headView.findViewById(R.id.round2);
- r2.setVisibility(View.GONE);
-
- addView(headView);
+ headView = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_view_bezier,
+ null, false);
+ waveView = (WaveView) headView.findComponentById(ResourceTable.Id_draweeView);
+ rippleView = (RippleView) headView.findComponentById(ResourceTable.Id_ripple);
+ r1 = (RoundDotView) headView.findComponentById(ResourceTable.Id_round1);
+ r2 = (RoundProgressView) headView.findComponentById(ResourceTable.Id_round2);
+ r2.setVisibility(VISIBLE);
+
+ addComponent(headView);
}
- public void setWaveColor(@ColorInt int color) {
+ public void setWaveColor(int color) {
waveView.setWaveColor(color);
}
- public void setRippleColor(@ColorInt int color) {
+ public void setRippleColor(int color) {
rippleView.setRippleColor(color);
}
@@ -81,35 +82,33 @@ public class BezierLayout extends FrameLayout implements IHeaderView {
return valve;
}
- private ValueAnimator waveAnimator, circleAnimator;
+ private AnimatorValue waveAnimator, circleAnimator;
- @Override
protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
if (waveAnimator != null) waveAnimator.cancel();
if (circleAnimator != null) circleAnimator.cancel();
}
@Override
- public View getView() {
+ public Component getView() {
return this;
}
@Override
public void onPullingDown(float fraction, float maxHeadHeight, float headHeight) {
- if (rippleView.getVisibility() == VISIBLE) rippleView.setVisibility(GONE);
+ if (rippleView.getVisibility() == VISIBLE) rippleView.setVisibility(HIDE);
waveView.setHeadHeight((int) (headHeight * limitValue(1, fraction)));
waveView.setWaveHeight((int) (maxHeadHeight * Math.max(0, fraction - 1)));
waveView.invalidate();
- /*处理圈圈**/
+ /* 处理圈圈 **/
r1.setCir_x((int) (30 * limitValue(1, fraction)));
- r1.setVisibility(View.VISIBLE);
+ r1.setVisibility(Component.VISIBLE);
r1.invalidate();
- r2.setVisibility(View.GONE);
- r2.animate().scaleX((float) 0.1);
- r2.animate().scaleY((float) 0.1);
+ r2.setVisibility(VISIBLE);
+ r2.setScaleX((float) 0.1);
+ r2.setScaleY((float) 0.1);
}
@Override
@@ -125,56 +124,103 @@ public class BezierLayout extends FrameLayout implements IHeaderView {
@Override
public void startAnim(float maxHeadHeight, float headHeight) {
waveView.setHeadHeight((int) headHeight);
- waveAnimator = ValueAnimator.ofInt(waveView.getWaveHeight(), 0, -300, 0, -100, 0);
- waveAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ AnimatorValueUtil animatorValueUtil = new AnimatorValueUtil();
+ animatorValueUtil.ofFloat(waveView.getWaveHeight(), 0, -300, 0, -100, 0);
+ waveAnimator = new AnimatorValue();
+ waveAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
@Override
- public void onAnimationUpdate(ValueAnimator animation) {
- waveView.setWaveHeight((int) animation.getAnimatedValue() / 2);
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ float value = animatorValueUtil.getValue(v);
+ waveView.setWaveHeight((int) value / 2);
waveView.invalidate();
-
}
});
- waveAnimator.setInterpolator(new DecelerateInterpolator());
+ waveAnimator.setCurveType(Animator.CurveType.DECELERATE);
waveAnimator.setDuration(800);
waveAnimator.start();
/*处理圈圈进度条**/
- circleAnimator = ValueAnimator.ofFloat(1, 0);
- circleAnimator.addListener(new AnimatorListenerAdapter() {
+ AnimatorValueUtil animatorValueUtil2 = new AnimatorValueUtil();
+ animatorValueUtil2.ofFloat(1, 0);
+ circleAnimator = new AnimatorValue();
+ circleAnimator.setStateChangedListener(new Animator.StateChangedListener() {
@Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- r1.setVisibility(GONE);
- r2.setVisibility(View.VISIBLE);
- r2.animate().scaleX((float) 1.0);
- r2.animate().scaleY((float) 1.0);
- r2.postDelayed(new Runnable() {
+ public void onStart(Animator animator) {
+
+ }
+
+ @Override
+ public void onStop(Animator animator) {
+
+ }
+
+ @Override
+ public void onCancel(Animator animator) {
+
+ }
+
+ @Override
+ public void onEnd(Animator animator) {
+ r1.setVisibility(VISIBLE);
+ r2.setVisibility(Component.VISIBLE);
+ r2.setScaleX((float) 1.0);
+ r2.setScaleY((float) 1.0);
+ new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
@Override
public void run() {
r2.startAnim();
}
}, 200);
}
+
+ @Override
+ public void onPause(Animator animator) {
+
+ }
+
+ @Override
+ public void onResume(Animator animator) {
+
+ }
});
- circleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ circleAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
@Override
- public void onAnimationUpdate(ValueAnimator animation) {
- float value = (float) animation.getAnimatedValue();
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ float value = animatorValueUtil2.getValue(v);
r1.setCir_x((int) (-value * 40));
r1.invalidate();
}
-
});
- circleAnimator.setInterpolator(new DecelerateInterpolator());
+ circleAnimator.setCurveType(Animator.CurveType.DECELERATE);
circleAnimator.setDuration(300);
circleAnimator.start();
}
+ public void releaseAnim(Component component, float start, float end) {
+ AnimatorValueUtil animatorValueUtil = new AnimatorValueUtil();
+ animatorValueUtil.ofFloat(start, end);
+ AnimatorValue releaseAnimator = new AnimatorValue();
+ releaseAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ float value = animatorValueUtil.getValue(v);
+ component.setHeight((int) value);
+
+ if (null != onRefreshListener) {
+ onRefreshListener.onRefresh();
+ }
+ }
+ });
+ releaseAnimator.setCurveType(Animator.CurveType.DECELERATE);
+ releaseAnimator.setDuration(250);
+ releaseAnimator.start();
+ }
+
@Override
public void onFinish(final OnAnimEndListener animEndListener) {
r2.stopAnim();
- r2.animate().scaleX((float) 0.0);
- r2.animate().scaleY((float) 0.0);
+ r2.setScaleX((float) 0.0);
+ r2.setScaleY((float) 0.0);
rippleView.setRippleEndListener(new RippleView.OnRippleEndListener() {
@Override
public void onRippleEnd() {
@@ -193,8 +239,14 @@ public class BezierLayout extends FrameLayout implements IHeaderView {
r2.stopAnim();
r2.setScaleX(0);
r2.setScaleY(0);
- r2.setVisibility(View.GONE);
+ r2.setVisibility(VISIBLE);
rippleView.stopAnim();
- rippleView.setVisibility(GONE);
+ rippleView.setVisibility(VISIBLE);
+ }
+
+ private OnRefreshListener onRefreshListener;
+
+ public void setRefreshListener(OnRefreshListener refreshlistener) {
+ onRefreshListener = refreshlistener;
}
}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RippleView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RippleView.java
index 655fe3cd4b7a316c544b558b79be8681c0bc66cd..3d057fdae1097bd2cf6e0d657e1c927fadb540a1 100755
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RippleView.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RippleView.java
@@ -1,20 +1,19 @@
package com.lcodecore.tkrefreshlayout.header.bezierlayout;
-
-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.support.annotation.ColorInt;
-import android.util.AttributeSet;
-import android.view.View;
+import com.lcodecore.tkrefreshlayout.utils.AnimatorValueUtil;
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
/**
* cjj
*/
-public class RippleView extends View {
+public class RippleView extends Component implements Component.DrawTask {
private Paint mPaint;
private int r;
private OnRippleEndListener listener;
@@ -31,48 +30,77 @@ public class RippleView extends View {
this(context, null, 0);
}
- public RippleView(Context context, AttributeSet attrs) {
+ public RippleView(Context context, AttrSet attrs) {
this(context, attrs, 0);
}
- public RippleView(Context context, AttributeSet attrs, int defStyleAttr) {
+ public RippleView(Context context, AttrSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
+ addDrawTask(this::onDraw);
}
- ValueAnimator va;
+ AnimatorValue va;
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
- mPaint.setColor(0xffffffff);
- mPaint.setStyle(Paint.Style.FILL);
+ mPaint.setColor(new Color(Color.getIntColor("#ffffff")));
+ mPaint.setStyle(Paint.Style.FILL_STYLE);
}
- public void setRippleColor(@ColorInt int color) {
- if (mPaint != null) mPaint.setColor(color);
+ public void setRippleColor(int color) {
+ if (mPaint != null) mPaint.setColor(new Color(color));
}
public void startReveal() {
setVisibility(VISIBLE);
if (va == null) {
int bigRadius = (int) (Math.sqrt(Math.pow(getHeight(), 2) + Math.pow(getWidth(), 2)));
- va = ValueAnimator.ofInt(0, bigRadius / 2);
+ AnimatorValueUtil animatorValueUtil = new AnimatorValueUtil();
+ animatorValueUtil.ofFloat(0, bigRadius / 2.0f);
+ va = new AnimatorValue();
va.setDuration(bigRadius);
- va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ va.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
@Override
- public void onAnimationUpdate(ValueAnimator animation) {
- r = (int) animation.getAnimatedValue() * 2;
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ float value = animatorValueUtil.getValue(v);
+ r = (int) value * 2;
invalidate();
}
});
- va.addListener(new AnimatorListenerAdapter() {
+ va.setStateChangedListener(new Animator.StateChangedListener() {
+ @Override
+ public void onStart(Animator animator) {
+
+ }
+
+ @Override
+ public void onStop(Animator animator) {
+
+ }
+
+ @Override
+ public void onCancel(Animator animator) {
+
+ }
+
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onEnd(Animator animator) {
if (listener != null) {
listener.onRippleEnd();
}
}
+
+ @Override
+ public void onPause(Animator animator) {
+
+ }
+
+ @Override
+ public void onResume(Animator animator) {
+
+ }
});
}
va.start();
@@ -83,14 +111,11 @@ public class RippleView extends View {
}
@Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- canvas.drawCircle(getWidth() / 2, getHeight() / 2, r, mPaint);
+ public void onDraw(Component component, Canvas canvas) {
+ canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, r, mPaint);
}
- @Override
protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
if (va != null) va.cancel();
}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RoundDotView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RoundDotView.java
index a4992d5850635b0da56a0149296f8eb9c534afac..b2fc5c635285079739194c9e57f8348abc18f258 100755
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RoundDotView.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RoundDotView.java
@@ -1,16 +1,16 @@
package com.lcodecore.tkrefreshlayout.header.bezierlayout;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.View;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
/**
* Created by cjj on 2015/8/27.
*/
-public class RoundDotView extends View {
+public class RoundDotView extends Component implements Component.DrawTask {
private Paint mPath;
private float r=15;
private int num = 7;
@@ -25,11 +25,11 @@ public class RoundDotView extends View {
this(context, null, 0);
}
- public RoundDotView(Context context, AttributeSet attrs) {
+ public RoundDotView(Context context, AttrSet attrs) {
this(context, attrs, 0);
}
- public RoundDotView(Context context, AttributeSet attrs, int defStyleAttr) {
+ public RoundDotView(Context context, AttrSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@@ -37,49 +37,46 @@ public class RoundDotView extends View {
private void init() {
mPath = new Paint();
mPath.setAntiAlias(true);
- mPath.setColor(Color.rgb(114,114,114));
+ mPath.setColor(new Color(Color.rgb(114,114,114)));
+ addDrawTask(this);
}
@Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- int w = getMeasuredWidth()/num-10;
+ public void onDraw(Component component, Canvas canvas) {
+ int w = getEstimatedWidth()/num-10;
for (int i = 0;i < num; i++)
{
switch (i)
{
case 0:
- mPath.setAlpha(35);
- canvas.drawCircle(getMeasuredWidth() / 2-cir_x*3 -3*w/3*2,getMeasuredHeight()/2,r,mPath);
+ mPath.setAlpha(0.1f);
+ canvas.drawCircle(getEstimatedWidth() / 2.0f-cir_x*3 -3*w/3*2,getEstimatedHeight()/2.0f,r,mPath);
break;
case 1:
- mPath.setAlpha(105);
- canvas.drawCircle(getMeasuredWidth() / 2-cir_x*2 -2*w/3*2,getMeasuredHeight()/2,r,mPath);
+ mPath.setAlpha(0.4f);
+ canvas.drawCircle(getEstimatedWidth() / 2.0f-cir_x*2 -2*w/3*2,getEstimatedHeight()/2.0f,r,mPath);
break;
case 2:
- mPath.setAlpha(145);
- canvas.drawCircle(getMeasuredWidth() / 2 -cir_x*1-w/3*2,getMeasuredHeight()/2,r,mPath);
+ mPath.setAlpha(0.7f);
+ canvas.drawCircle(getEstimatedWidth() / 2.0f -cir_x * 1-w/3.0f * 2.0f,getEstimatedHeight()/2.0f,r,mPath);
break;
case 3:
- mPath.setAlpha(255);
- canvas.drawCircle(getMeasuredWidth() / 2 ,getMeasuredHeight()/2,r,mPath);
+ mPath.setAlpha(1);
+ canvas.drawCircle(getEstimatedWidth() / 2.0f ,getEstimatedHeight()/2.0f,r,mPath);
break;
case 4:
- mPath.setAlpha(145);
- canvas.drawCircle(getMeasuredWidth() / 2 +cir_x*1+w/3*2,getMeasuredHeight()/2,r,mPath);
+ mPath.setAlpha(0.7f);
+ canvas.drawCircle(getEstimatedWidth() / 2.0f +cir_x*1+w/3.0f*2.0f,getEstimatedHeight()/2.0f,r,mPath);
break;
case 5:
- mPath.setAlpha(105);
- canvas.drawCircle(getMeasuredWidth() / 2 +cir_x*2+2*w/3*2,getMeasuredHeight()/2,r,mPath);
+ mPath.setAlpha(0.4f);
+ canvas.drawCircle(getEstimatedWidth() / 2.0f +cir_x*2+2*w/3.0f*2.0f,getEstimatedHeight()/2.0f,r,mPath);
break;
case 6:
- mPath.setAlpha(35);
- canvas.drawCircle(getMeasuredWidth() / 2 +cir_x*3+3*w/3*2,getMeasuredHeight()/2,r,mPath);
+ mPath.setAlpha(0.1f);
+ canvas.drawCircle(getEstimatedWidth() / 2.0f +cir_x*3+3*w/3.0f*2.0f,getEstimatedHeight()/2.0f,r,mPath);
break;
}
-
}
}
-
-
}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RoundProgressView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RoundProgressView.java
index 8bc110784efcb3f029a9c1f6239c3dfb0b964c64..c9410327ecf2f9459084f5ee5f17c71a270673b1 100755
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RoundProgressView.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RoundProgressView.java
@@ -1,48 +1,44 @@
package com.lcodecore.tkrefreshlayout.header.bezierlayout;
-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.util.AttributeSet;
-import android.view.View;
-import android.view.animation.AccelerateDecelerateInterpolator;
+import com.lcodecore.tkrefreshlayout.utils.AnimatorValueUtil;
+import com.lcodecore.tkrefreshlayout.utils.RectF;
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.render.Arc;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
/**
* Created by Administrator on 2015/8/27.
*/
-public class RoundProgressView extends View {
+public class RoundProgressView extends Component implements Component.DrawTask {
private Paint mPath;
private Paint mPantR;
private float r = 40;
- private int num = 7;
private int stratAngle = 270;
private int endAngle = 0;
private int outCir_value = 15;
- public void setCir_x(int cir_x) {
- this.cir_x = cir_x;
- }
-
- private int cir_x;
-
public RoundProgressView(Context context) {
this(context, null, 0);
}
- public RoundProgressView(Context context, AttributeSet attrs) {
+ public RoundProgressView(Context context, AttrSet attrs) {
this(context, attrs, 0);
}
- public RoundProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
+ public RoundProgressView(Context context, AttrSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
+ addDrawTask(this::onDraw);
}
- ValueAnimator va;
+ AnimatorValue va;
private void init() {
mPath = new Paint();
@@ -50,51 +46,53 @@ public class RoundProgressView extends View {
mPantR.setColor(Color.WHITE);
mPantR.setAntiAlias(true);
mPath.setAntiAlias(true);
- mPath.setColor(Color.rgb(114, 114, 114));
+ mPath.setColor(new Color(Color.rgb(114, 114, 114)));
- va = ValueAnimator.ofInt(0, 360);
+ AnimatorValueUtil animatorValueUtil = new AnimatorValueUtil();
+ animatorValueUtil.ofFloat(0, 360);
+
+ va = new AnimatorValue();
va.setDuration(720);
- va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ va.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
@Override
- public void onAnimationUpdate(ValueAnimator animation) {
- endAngle = (int) animation.getAnimatedValue();
- postInvalidate();
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ float value = animatorValueUtil.getValue(v);
+ endAngle = (int) value;
+ invalidate();
}
});
- va.setRepeatCount(ValueAnimator.INFINITE);
- va.setInterpolator(new AccelerateDecelerateInterpolator());
+ va.setLoopedCount(2);
+ va.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
}
private RectF oval, oval2;
@Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- int w = getMeasuredWidth() / num - 10;
- mPath.setStyle(Paint.Style.FILL);
- canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, r, mPath);
+ public void onDraw(Component component, Canvas canvas) {
+ mPath.setStyle(Paint.Style.FILL_STYLE);
+ canvas.drawCircle(getEstimatedWidth() / 2.0f, getEstimatedHeight() / 2.0f, r, mPath);
canvas.save();
- mPath.setStyle(Paint.Style.STROKE);//设置为空心
+ mPath.setStyle(Paint.Style.STROKE_STYLE);//设置为空心
mPath.setStrokeWidth(6);
- canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, r + 15, mPath);
+ canvas.drawCircle(getEstimatedWidth() / 2.0f, getEstimatedHeight() / 2.0f, r + 15, mPath);
canvas.restore();
- mPantR.setStyle(Paint.Style.FILL);
+ mPantR.setStyle(Paint.Style.FILL_STYLE);
if (oval == null) oval = new RectF();
- oval.set(getMeasuredWidth() / 2 - r, getMeasuredHeight() / 2 - r, getMeasuredWidth() / 2 + r, getMeasuredHeight() / 2 + r);// 设置个新的长方形,扫描测量
- canvas.drawArc(oval, stratAngle, endAngle, true, mPantR);
+ oval = new RectF(getEstimatedWidth() / 2.0f - r, getEstimatedHeight() / 2.0f - r
+ , getEstimatedWidth() / 2.0f + r, getEstimatedHeight() / 2.0f + r);// 设置个新的长方形,扫描测量
+ canvas.drawArc(oval, new Arc(stratAngle, endAngle, true), mPantR);
canvas.save();
mPantR.setStrokeWidth(6);
- mPantR.setStyle(Paint.Style.STROKE);
+ mPantR.setStyle(Paint.Style.STROKE_STYLE);
if (oval2 == null) oval2 = new RectF();
- oval2.set(getMeasuredWidth() / 2 - r - outCir_value, getMeasuredHeight() / 2 - r - outCir_value, getMeasuredWidth() / 2 + r + outCir_value, getMeasuredHeight() / 2 + r + outCir_value);// 设置个新的长方形,扫描测量
- canvas.drawArc(oval2, stratAngle, endAngle, false, mPantR);
+ oval2 = new RectF(getEstimatedWidth() / 2.0f - r - outCir_value, getEstimatedHeight() / 2.0f - r - outCir_value
+ , getEstimatedWidth() / 2.0f + r + outCir_value, getEstimatedHeight() / 2.0f + r + outCir_value);// 设置个新的长方形,扫描测量
+ canvas.drawArc(oval2, new Arc(stratAngle, endAngle, false), mPantR);
canvas.restore();
}
- @Override
protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
if (va != null) va.cancel();
}
@@ -105,5 +103,4 @@ public class RoundProgressView extends View {
public void stopAnim() {
if (va != null && va.isRunning()) va.cancel();
}
-
}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/WaveView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/WaveView.java
index 271c92ec1882e1119cc800753e8ba6466d8204c0..6726093946b95592815139b2c79426f2548c9b90 100755
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/WaveView.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/WaveView.java
@@ -1,21 +1,17 @@
package com.lcodecore.tkrefreshlayout.header.bezierlayout;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.Drawable;
-import android.support.annotation.ColorInt;
-import android.util.AttributeSet;
-import android.view.View;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.render.Path;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
/**
* Created by cjj on 2015/8/5.
* 绘制贝塞尔来绘制波浪形
*/
-public class WaveView extends View {
+public class WaveView extends Component implements Component.DrawTask {
private int waveHeight;
private int headHeight;
Path path;
@@ -25,20 +21,21 @@ public class WaveView extends View {
this(context, null, 0);
}
- public WaveView(Context context, AttributeSet attrs) {
+ public WaveView(Context context, AttrSet attrs) {
this(context, attrs, 0);
}
- public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
+ public WaveView(Context context, AttrSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr+"");
init();
}
private void init() {
path = new Path();
paint = new Paint();
- paint.setColor(0xff1F2426);
+ paint.setColor(new Color(Color.getIntColor("#1F2426")));
paint.setAntiAlias(true);
+ addDrawTask(this);
}
public int getHeadHeight() {
@@ -57,33 +54,18 @@ public class WaveView extends View {
this.waveHeight = waveHeight;
}
- public void setWaveColor(@ColorInt int color) {
- if (paint != null) paint.setColor(color);
+ public void setWaveColor(int color) {
+ if (paint != null) paint.setColor(new Color(color));
}
@Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
+ public void onDraw(Component component, Canvas canvas) {
//重置画笔
path.reset();
path.lineTo(0, headHeight);
//绘制贝塞尔曲线
- path.quadTo(getMeasuredWidth() / 2, headHeight + waveHeight, getMeasuredWidth(), headHeight);
- path.lineTo(getMeasuredWidth(), 0);
+ path.quadTo(getEstimatedWidth() / 2.0f, headHeight + waveHeight, getEstimatedWidth(), headHeight);
+ path.lineTo(getEstimatedWidth(), 0);
canvas.drawPath(path, paint);
}
-
-
- static Bitmap drawableToBitmap(Drawable drawable) // drawable 转换成bitmap
- {
- int width = drawable.getIntrinsicWidth();// 取drawable的长宽
- int height = drawable.getIntrinsicHeight();
- Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;// 取drawable的颜色格式
- Bitmap bitmap = Bitmap.createBitmap(width, height, config);// 建立对应bitmap
- Canvas canvas = new Canvas(bitmap);// 建立对应bitmap的画布
- drawable.setBounds(0, 0, width, height);
- drawable.draw(canvas);// 把drawable内容画到画布中
- return bitmap;
- }
-
}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/progresslayout/CircleImageView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/progresslayout/CircleImageView.java
deleted file mode 100644
index 5ee466c5e3c3ef6215bb5d4ef3524da629080f4c..0000000000000000000000000000000000000000
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/progresslayout/CircleImageView.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package com.lcodecore.tkrefreshlayout.header.progresslayout;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.RadialGradient;
-import android.graphics.Shader;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.OvalShape;
-import android.support.v4.view.ViewCompat;
-import android.view.animation.Animation;
-import android.widget.ImageView;
-
-/**
- * Private class created to work around issues with AnimationListeners being
- * called before the animation is actually complete and support shadows on older
- * platforms.
- *
- */
-public class CircleImageView extends ImageView {
-
- private static final int KEY_SHADOW_COLOR = 0x1E000000;
- private static final int FILL_SHADOW_COLOR = 0x3D000000;
- // PX
- private static final float X_OFFSET = 0f;
- private static final float Y_OFFSET = 1.75f;
- private static final float SHADOW_RADIUS = 3.5f;
- private static final int SHADOW_ELEVATION = 4;
-
- private Animation.AnimationListener mListener;
- private int mShadowRadius;
-
- public CircleImageView(Context context, int color, final float radius) {
- super(context);
- final float density = getContext().getResources().getDisplayMetrics().density;
- final int diameter = (int) (radius * density * 2);
- final int shadowYOffset = (int) (density * Y_OFFSET);
- final int shadowXOffset = (int) (density * X_OFFSET);
-
- mShadowRadius = (int) (density * SHADOW_RADIUS);
-
- ShapeDrawable circle;
- if (elevationSupported()) {
- circle = new ShapeDrawable(new OvalShape());
- ViewCompat.setElevation(this, SHADOW_ELEVATION * density);
- } else {
- OvalShape oval = new OvalShadow(mShadowRadius, diameter);
- circle = new ShapeDrawable(oval);
- ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, circle.getPaint());
- circle.getPaint().setShadowLayer(mShadowRadius, shadowXOffset, shadowYOffset,
- KEY_SHADOW_COLOR);
- final int padding = mShadowRadius;
- // set padding so the inner image sits correctly within the shadow.
- setPadding(padding, padding, padding, padding);
- }
- circle.getPaint().setColor(color);
- setBackgroundDrawable(circle);
- }
-
- private boolean elevationSupported() {
- return android.os.Build.VERSION.SDK_INT >= 21;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- if (!elevationSupported()) {
- setMeasuredDimension(getMeasuredWidth() + mShadowRadius*2, getMeasuredHeight()
- + mShadowRadius*2);
- }
- }
-
- public void setAnimationListener(Animation.AnimationListener listener) {
- mListener = listener;
- }
-
- @Override
- public void onAnimationStart() {
- super.onAnimationStart();
- if (mListener != null) {
- mListener.onAnimationStart(getAnimation());
- }
- }
-
- @Override
- public void onAnimationEnd() {
- super.onAnimationEnd();
- if (mListener != null) {
- mListener.onAnimationEnd(getAnimation());
- }
- }
-
- /**
- * Update the background color of the circle image view.
- *
- * @param colorRes Id of a color resource.
- */
- public void setBackgroundColorRes(int colorRes) {
- setBackgroundColor(getContext().getResources().getColor(colorRes));
- }
-
- @Override
- public void setBackgroundColor(int color) {
- if (getBackground() instanceof ShapeDrawable) {
- ((ShapeDrawable) getBackground()).getPaint().setColor(color);
- }
- }
-
- private class OvalShadow extends OvalShape {
- private RadialGradient mRadialGradient;
- private Paint mShadowPaint;
- private int mCircleDiameter;
-
- public OvalShadow(int shadowRadius, int circleDiameter) {
- super();
- mShadowPaint = new Paint();
- mShadowRadius = shadowRadius;
- mCircleDiameter = circleDiameter;
- mRadialGradient = new RadialGradient(mCircleDiameter / 2, mCircleDiameter / 2,
- mShadowRadius, new int[] {
- FILL_SHADOW_COLOR, Color.TRANSPARENT
- }, null, Shader.TileMode.CLAMP);
- mShadowPaint.setShader(mRadialGradient);
- }
-
- @Override
- public void draw(Canvas canvas, Paint paint) {
- final int viewWidth = CircleImageView.this.getWidth();
- final int viewHeight = CircleImageView.this.getHeight();
- canvas.drawCircle(viewWidth / 2, viewHeight / 2, (mCircleDiameter / 2 + mShadowRadius),
- mShadowPaint);
- canvas.drawCircle(viewWidth / 2, viewHeight / 2, (mCircleDiameter / 2), paint);
- }
- }
-}
\ No newline at end of file
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/progresslayout/MaterialProgressDrawable.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/progresslayout/MaterialProgressDrawable.java
deleted file mode 100644
index e688ba8a52f6d9ce5c0be93bdf5fa258f135a77a..0000000000000000000000000000000000000000
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/progresslayout/MaterialProgressDrawable.java
+++ /dev/null
@@ -1,775 +0,0 @@
-package com.lcodecore.tkrefreshlayout.header.progresslayout;
-
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.view.animation.Animation;
-import android.view.animation.LinearInterpolator;
-import android.view.animation.Transformation;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.Paint.Style;
-import android.graphics.Path;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Animatable;
-import android.support.annotation.IntDef;
-import android.support.annotation.NonNull;
-import android.support.v4.view.animation.FastOutSlowInInterpolator;
-import android.util.DisplayMetrics;
-import android.view.View;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-
-/**
- * Fancy progress indicator for Material theme.
- *
- */
-public class MaterialProgressDrawable extends Drawable implements Animatable {
- private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
- private static final Interpolator MATERIAL_INTERPOLATOR = new FastOutSlowInInterpolator();
-
- private static final float FULL_ROTATION = 1080.0f;
- @Retention(RetentionPolicy.CLASS)
- @IntDef({LARGE, DEFAULT})
- public @interface ProgressDrawableSize {}
- // Maps to ProgressBar.Large style
- static final int LARGE = 0;
- // Maps to ProgressBar default style
- static final int DEFAULT = 1;
-
- // Maps to ProgressBar default style
- private static final int CIRCLE_DIAMETER = 40;
- private static final float CENTER_RADIUS = 8.75f; //should add up to 10 when + stroke_width
- private static final float STROKE_WIDTH = 2.5f;
-
- // Maps to ProgressBar.Large style
- private static final int CIRCLE_DIAMETER_LARGE = 56;
- private static final float CENTER_RADIUS_LARGE = 12.5f;
- private static final float STROKE_WIDTH_LARGE = 3f;
-
- private final int[] COLORS = new int[] {
- Color.BLACK
- };
-
- /**
- * The value in the linear interpolator for animating the drawable at which
- * the color transition should start
- */
- private static final float COLOR_START_DELAY_OFFSET = 0.75f;
- private static final float END_TRIM_START_DELAY_OFFSET = 0.5f;
- private static final float START_TRIM_DURATION_OFFSET = 0.5f;
-
- /** The duration of a single progress spin in milliseconds. */
- private static final int ANIMATION_DURATION = 1332;
-
- /** The number of points in the progress "star". */
- private static final float NUM_POINTS = 5f;
- /** The list of animators operating on this drawable. */
- private final ArrayList mAnimators = new ArrayList();
-
- /** The indicator ring, used to manage animation state. */
- private final Ring mRing;
-
- /** Canvas rotation in degrees. */
- private float mRotation;
-
- /** Layout info for the arrowhead in dp */
- private static final int ARROW_WIDTH = 10;
- private static final int ARROW_HEIGHT = 5;
- private static final float ARROW_OFFSET_ANGLE = 5;
-
- /** Layout info for the arrowhead for the large spinner in dp */
- private static final int ARROW_WIDTH_LARGE = 12;
- private static final int ARROW_HEIGHT_LARGE = 6;
- private static final float MAX_PROGRESS_ARC = .8f;
-
- private Resources mResources;
- private View mParent;
- private Animation mAnimation;
- private float mRotationCount;
- private double mWidth;
- private double mHeight;
- boolean mFinishing;
-
- public MaterialProgressDrawable(Context context, View parent) {
- mParent = parent;
- mResources = context.getResources();
-
- mRing = new Ring(mCallback);
- mRing.setColors(COLORS);
-
- updateSizes(DEFAULT);
- setupAnimators();
- }
-
- private void setSizeParameters(double progressCircleWidth, double progressCircleHeight,
- double centerRadius, double strokeWidth, float arrowWidth, float arrowHeight) {
- final Ring ring = mRing;
- final DisplayMetrics metrics = mResources.getDisplayMetrics();
- final float screenDensity = metrics.density;
-
- mWidth = progressCircleWidth * screenDensity;
- mHeight = progressCircleHeight * screenDensity;
- ring.setStrokeWidth((float) strokeWidth * screenDensity);
- ring.setCenterRadius(centerRadius * screenDensity);
- ring.setColorIndex(0);
- ring.setArrowDimensions(arrowWidth * screenDensity, arrowHeight * screenDensity);
- ring.setInsets((int) mWidth, (int) mHeight);
- }
-
- /**
- * Set the overall size for the progress spinner. This updates the radius
- * and stroke width of the ring.
- *
- * @param size One of { MaterialProgressDrawable.LARGE} or
- * {MaterialProgressDrawable.DEFAULT}
- */
- public void updateSizes(@ProgressDrawableSize int size) {
- if (size == LARGE) {
- setSizeParameters(CIRCLE_DIAMETER_LARGE, CIRCLE_DIAMETER_LARGE, CENTER_RADIUS_LARGE,
- STROKE_WIDTH_LARGE, ARROW_WIDTH_LARGE, ARROW_HEIGHT_LARGE);
- } else {
- setSizeParameters(CIRCLE_DIAMETER, CIRCLE_DIAMETER, CENTER_RADIUS, STROKE_WIDTH,
- ARROW_WIDTH, ARROW_HEIGHT);
- }
- }
-
- /**
- * @param show Set to true to display the arrowhead on the progress spinner.
- */
- public void showArrow(boolean show) {
- mRing.setShowArrow(show);
- }
-
- /**
- * @param scale Set the scale of the arrowhead for the spinner.
- */
- public void setArrowScale(float scale) {
- mRing.setArrowScale(scale);
- }
-
- /**
- * Set the start and end trim for the progress spinner arc.
- *
- * @param startAngle start angle
- * @param endAngle end angle
- */
- public void setStartEndTrim(float startAngle, float endAngle) {
- mRing.setStartTrim(startAngle);
- mRing.setEndTrim(endAngle);
- }
-
- /**
- * Set the amount of rotation to apply to the progress spinner.
- *
- * @param rotation Rotation is from [0..1]
- */
- public void setProgressRotation(float rotation) {
- mRing.setRotation(rotation);
- }
-
- /**
- * Update the background color of the circle image view.
- */
- public void setBackgroundColor(int color) {
- mRing.setBackgroundColor(color);
- }
-
- /**
- * Set the colors used in the progress animation from color resources.
- * The first color will also be the color of the bar that grows in response
- * to a user swipe gesture.
- *
- * @param colors
- */
- public void setColorSchemeColors(int... colors) {
- mRing.setColors(colors);
- mRing.setColorIndex(0);
- }
-
- @Override
- public int getIntrinsicHeight() {
- return (int) mHeight;
- }
-
- @Override
- public int getIntrinsicWidth() {
- return (int) mWidth;
- }
-
- @Override
- public void draw(Canvas c) {
- final Rect bounds = getBounds();
- final int saveCount = c.save();
- c.rotate(mRotation, bounds.exactCenterX(), bounds.exactCenterY());
- mRing.draw(c, bounds);
- c.restoreToCount(saveCount);
- }
-
- @Override
- public void setAlpha(int alpha) {
- mRing.setAlpha(alpha);
- }
-
- public int getAlpha() {
- return mRing.getAlpha();
- }
-
- @Override
- public void setColorFilter(ColorFilter colorFilter) {
- mRing.setColorFilter(colorFilter);
- }
-
- @SuppressWarnings("unused")
- void setRotation(float rotation) {
- mRotation = rotation;
- invalidateSelf();
- }
-
- @SuppressWarnings("unused")
- private float getRotation() {
- return mRotation;
- }
-
- @Override
- public int getOpacity() {
- return PixelFormat.TRANSLUCENT;
- }
-
- @Override
- public boolean isRunning() {
- final ArrayList animators = mAnimators;
- final int N = animators.size();
- for (int i = 0; i < N; i++) {
- final Animation animator = animators.get(i);
- if (animator.hasStarted() && !animator.hasEnded()) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public void start() {
- mAnimation.reset();
- mRing.storeOriginals();
- // Already showing some part of the ring
- if (mRing.getEndTrim() != mRing.getStartTrim()) {
- mFinishing = true;
- mAnimation.setDuration(ANIMATION_DURATION/2);
- mParent.startAnimation(mAnimation);
- } else {
- mRing.setColorIndex(0);
- mRing.resetOriginals();
- mAnimation.setDuration(ANIMATION_DURATION);
- mParent.startAnimation(mAnimation);
- }
- }
-
- @Override
- public void stop() {
- mParent.clearAnimation();
- setRotation(0);
- mRing.setShowArrow(false);
- mRing.setColorIndex(0);
- mRing.resetOriginals();
- }
-
- private float getMinProgressArc(Ring ring) {
- return (float) Math.toRadians(
- ring.getStrokeWidth() / (2 * Math.PI * ring.getCenterRadius()));
- }
-
- // Adapted from ArgbEvaluator.java
- private int evaluateColorChange(float fraction, int startValue, int endValue) {
- int startInt = (Integer) startValue;
- int startA = (startInt >> 24) & 0xff;
- int startR = (startInt >> 16) & 0xff;
- int startG = (startInt >> 8) & 0xff;
- int startB = startInt & 0xff;
-
- int endInt = (Integer) endValue;
- int endA = (endInt >> 24) & 0xff;
- int endR = (endInt >> 16) & 0xff;
- int endG = (endInt >> 8) & 0xff;
- int endB = endInt & 0xff;
-
- return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
- (int)((startR + (int)(fraction * (endR - startR))) << 16) |
- (int)((startG + (int)(fraction * (endG - startG))) << 8) |
- (int)((startB + (int)(fraction * (endB - startB))));
- }
-
- /**
- * Update the ring color if this is within the last 25% of the animation.
- * The new ring color will be a translation from the starting ring color to
- * the next color.
- */
- private void updateRingColor(float interpolatedTime, Ring ring) {
- if (interpolatedTime > COLOR_START_DELAY_OFFSET) {
- // scale the interpolatedTime so that the full
- // transformation from 0 - 1 takes place in the
- // remaining time
- ring.setColor(evaluateColorChange((interpolatedTime - COLOR_START_DELAY_OFFSET)
- / (1.0f - COLOR_START_DELAY_OFFSET), ring.getStartingColor(),
- ring.getNextColor()));
- }
- }
-
- private void applyFinishTranslation(float interpolatedTime, Ring ring) {
- // shrink back down and complete a full rotation before
- // starting other circles
- // Rotation goes between [0..1].
- updateRingColor(interpolatedTime, ring);
- float targetRotation = (float) (Math.floor(ring.getStartingRotation() / MAX_PROGRESS_ARC)
- + 1f);
- final float minProgressArc = getMinProgressArc(ring);
- final float startTrim = ring.getStartingStartTrim()
- + (ring.getStartingEndTrim() - minProgressArc - ring.getStartingStartTrim())
- * interpolatedTime;
- ring.setStartTrim(startTrim);
- ring.setEndTrim(ring.getStartingEndTrim());
- final float rotation = ring.getStartingRotation()
- + ((targetRotation - ring.getStartingRotation()) * interpolatedTime);
- ring.setRotation(rotation);
- }
-
- private void setupAnimators() {
- final Ring ring = mRing;
- final Animation animation = new Animation() {
- @Override
- public void applyTransformation(float interpolatedTime, Transformation t) {
- if (mFinishing) {
- applyFinishTranslation(interpolatedTime, ring);
- } else {
- // The minProgressArc is calculated from 0 to create an
- // angle that matches the stroke width.
- final float minProgressArc = getMinProgressArc(ring);
- final float startingEndTrim = ring.getStartingEndTrim();
- final float startingTrim = ring.getStartingStartTrim();
- final float startingRotation = ring.getStartingRotation();
-
- updateRingColor(interpolatedTime, ring);
-
- // Moving the start trim only occurs in the first 50% of a
- // single ring animation
- if (interpolatedTime <= START_TRIM_DURATION_OFFSET) {
- // scale the interpolatedTime so that the full
- // transformation from 0 - 1 takes place in the
- // remaining time
- final float scaledTime = (interpolatedTime)
- / (1.0f - START_TRIM_DURATION_OFFSET);
- final float startTrim = startingTrim
- + ((MAX_PROGRESS_ARC - minProgressArc) * MATERIAL_INTERPOLATOR
- .getInterpolation(scaledTime));
- ring.setStartTrim(startTrim);
- }
-
- // Moving the end trim starts after 50% of a single ring
- // animation completes
- if (interpolatedTime > END_TRIM_START_DELAY_OFFSET) {
- // scale the interpolatedTime so that the full
- // transformation from 0 - 1 takes place in the
- // remaining time
- final float minArc = MAX_PROGRESS_ARC - minProgressArc;
- float scaledTime = (interpolatedTime - START_TRIM_DURATION_OFFSET)
- / (1.0f - START_TRIM_DURATION_OFFSET);
- final float endTrim = startingEndTrim
- + (minArc * MATERIAL_INTERPOLATOR.getInterpolation(scaledTime));
- ring.setEndTrim(endTrim);
- }
-
- final float rotation = startingRotation + (0.25f * interpolatedTime);
- ring.setRotation(rotation);
-
- float groupRotation = ((FULL_ROTATION / NUM_POINTS) * interpolatedTime)
- + (FULL_ROTATION * (mRotationCount / NUM_POINTS));
- setRotation(groupRotation);
- }
- }
- };
- animation.setRepeatCount(Animation.INFINITE);
- animation.setRepeatMode(Animation.RESTART);
- animation.setInterpolator(LINEAR_INTERPOLATOR);
- animation.setAnimationListener(new Animation.AnimationListener() {
-
- @Override
- public void onAnimationStart(Animation animation) {
- mRotationCount = 0;
- }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- // do nothing
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
- ring.storeOriginals();
- ring.goToNextColor();
- ring.setStartTrim(ring.getEndTrim());
- if (mFinishing) {
- // finished closing the last ring from the swipe gesture; go
- // into progress mode
- mFinishing = false;
- animation.setDuration(ANIMATION_DURATION);
- ring.setShowArrow(false);
- } else {
- mRotationCount = (mRotationCount + 1) % (NUM_POINTS);
- }
- }
- });
- mAnimation = animation;
- }
-
- private final Callback mCallback = new Callback() {
- @Override
- public void invalidateDrawable(Drawable d) {
- invalidateSelf();
- }
-
- @Override
- public void scheduleDrawable(Drawable d, Runnable what, long when) {
- scheduleSelf(what, when);
- }
-
- @Override
- public void unscheduleDrawable(Drawable d, Runnable what) {
- unscheduleSelf(what);
- }
- };
-
- private static class Ring {
- private final RectF mTempBounds = new RectF();
- private final Paint mPaint = new Paint();
- private final Paint mArrowPaint = new Paint();
-
- private final Callback mCallback;
-
- private float mStartTrim = 0.0f;
- private float mEndTrim = 0.0f;
- private float mRotation = 0.0f;
- private float mStrokeWidth = 5.0f;
- private float mStrokeInset = 2.5f;
-
- private int[] mColors;
- // mColorIndex represents the offset into the available mColors that the
- // progress circle should currently display. As the progress circle is
- // animating, the mColorIndex moves by one to the next available color.
- private int mColorIndex;
- private float mStartingStartTrim;
- private float mStartingEndTrim;
- private float mStartingRotation;
- private boolean mShowArrow;
- private Path mArrow;
- private float mArrowScale;
- private double mRingCenterRadius;
- private int mArrowWidth;
- private int mArrowHeight;
- private int mAlpha;
- private final Paint mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- private int mBackgroundColor;
- private int mCurrentColor;
-
- public Ring(Callback callback) {
- mCallback = callback;
-
- mPaint.setStrokeCap(Paint.Cap.SQUARE);
- mPaint.setAntiAlias(true);
- mPaint.setStyle(Style.STROKE);
-
- mArrowPaint.setStyle(Paint.Style.FILL);
- mArrowPaint.setAntiAlias(true);
- }
-
- public void setBackgroundColor(int color) {
- mBackgroundColor = color;
- }
-
- /**
- * Set the dimensions of the arrowhead.
- *
- * @param width Width of the hypotenuse of the arrow head
- * @param height Height of the arrow point
- */
- public void setArrowDimensions(float width, float height) {
- mArrowWidth = (int) width;
- mArrowHeight = (int) height;
- }
-
- /**
- * Draw the progress spinner
- */
- public void draw(Canvas c, Rect bounds) {
- final RectF arcBounds = mTempBounds;
- arcBounds.set(bounds);
- arcBounds.inset(mStrokeInset, mStrokeInset);
-
- final float startAngle = (mStartTrim + mRotation) * 360;
- final float endAngle = (mEndTrim + mRotation) * 360;
- float sweepAngle = endAngle - startAngle;
-
- mPaint.setColor(mCurrentColor);
- c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);
-
- drawTriangle(c, startAngle, sweepAngle, bounds);
-
- if (mAlpha < 255) {
- mCirclePaint.setColor(mBackgroundColor);
- mCirclePaint.setAlpha(255 - mAlpha);
- c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2,
- mCirclePaint);
- }
- }
-
- private void drawTriangle(Canvas c, float startAngle, float sweepAngle, Rect bounds) {
- if (mShowArrow) {
- if (mArrow == null) {
- mArrow = new android.graphics.Path();
- mArrow.setFillType(android.graphics.Path.FillType.EVEN_ODD);
- } else {
- mArrow.reset();
- }
-
- // Adjust the position of the triangle so that it is inset as
- // much as the arc, but also centered on the arc.
- float inset = (int) mStrokeInset / 2 * mArrowScale;
- float x = (float) (mRingCenterRadius * Math.cos(0) + bounds.exactCenterX());
- float y = (float) (mRingCenterRadius * Math.sin(0) + bounds.exactCenterY());
-
- // Update the path each time. This works around an issue in SKIA
- // where concatenating a rotation matrix to a scale matrix
- // ignored a starting negative rotation. This appears to have
- // been fixed as of API 21.
- mArrow.moveTo(0, 0);
- mArrow.lineTo(mArrowWidth * mArrowScale, 0);
- mArrow.lineTo((mArrowWidth * mArrowScale / 2), (mArrowHeight
- * mArrowScale));
- mArrow.offset(x - inset, y);
- mArrow.close();
- // draw a triangle
- mArrowPaint.setColor(mCurrentColor);
- c.rotate(startAngle + sweepAngle - ARROW_OFFSET_ANGLE, bounds.exactCenterX(),
- bounds.exactCenterY());
- c.drawPath(mArrow, mArrowPaint);
- }
- }
-
- /**
- * Set the colors the progress spinner alternates between.
- *
- * @param colors Array of integers describing the colors. Must be non-null
.
- */
- public void setColors(@NonNull int[] colors) {
- mColors = colors;
- // if colors are reset, make sure to reset the color index as well
- setColorIndex(0);
- }
-
- /**
- * Set the absolute color of the progress spinner. This is should only
- * be used when animating between current and next color when the
- * spinner is rotating.
- *
- * @param color int describing the color.
- */
- public void setColor(int color) {
- mCurrentColor = color;
- }
-
- /**
- * @param index Index into the color array of the color to display in
- * the progress spinner.
- */
- public void setColorIndex(int index) {
- mColorIndex = index;
- mCurrentColor = mColors[mColorIndex];
- }
-
- /**
- * @return int describing the next color the progress spinner should use when drawing.
- */
- public int getNextColor() {
- return mColors[getNextColorIndex()];
- }
-
- private int getNextColorIndex() {
- return (mColorIndex + 1) % (mColors.length);
- }
-
- /**
- * Proceed to the next available ring color. This will automatically
- * wrap back to the beginning of colors.
- */
- public void goToNextColor() {
- setColorIndex(getNextColorIndex());
- }
-
- public void setColorFilter(ColorFilter filter) {
- mPaint.setColorFilter(filter);
- invalidateSelf();
- }
-
- /**
- * @param alpha Set the alpha of the progress spinner and associated arrowhead.
- */
- public void setAlpha(int alpha) {
- mAlpha = alpha;
- }
-
- /**
- * @return Current alpha of the progress spinner and arrowhead.
- */
- public int getAlpha() {
- return mAlpha;
- }
-
- /**
- * @param strokeWidth Set the stroke width of the progress spinner in pixels.
- */
- public void setStrokeWidth(float strokeWidth) {
- mStrokeWidth = strokeWidth;
- mPaint.setStrokeWidth(strokeWidth);
- invalidateSelf();
- }
-
- @SuppressWarnings("unused")
- public float getStrokeWidth() {
- return mStrokeWidth;
- }
-
- @SuppressWarnings("unused")
- public void setStartTrim(float startTrim) {
- mStartTrim = startTrim;
- invalidateSelf();
- }
-
- @SuppressWarnings("unused")
- public float getStartTrim() {
- return mStartTrim;
- }
-
- public float getStartingStartTrim() {
- return mStartingStartTrim;
- }
-
- public float getStartingEndTrim() {
- return mStartingEndTrim;
- }
-
- public int getStartingColor() {
- return mColors[mColorIndex];
- }
-
- @SuppressWarnings("unused")
- public void setEndTrim(float endTrim) {
- mEndTrim = endTrim;
- invalidateSelf();
- }
-
- @SuppressWarnings("unused")
- public float getEndTrim() {
- return mEndTrim;
- }
-
- @SuppressWarnings("unused")
- public void setRotation(float rotation) {
- mRotation = rotation;
- invalidateSelf();
- }
-
- @SuppressWarnings("unused")
- public float getRotation() {
- return mRotation;
- }
-
- public void setInsets(int width, int height) {
- final float minEdge = (float) Math.min(width, height);
- float insets;
- if (mRingCenterRadius <= 0 || minEdge < 0) {
- insets = (float) Math.ceil(mStrokeWidth / 2.0f);
- } else {
- insets = (float) (minEdge / 2.0f - mRingCenterRadius);
- }
- mStrokeInset = insets;
- }
-
- @SuppressWarnings("unused")
- public float getInsets() {
- return mStrokeInset;
- }
-
- /**
- * @param centerRadius Inner radius in px of the circle the progress
- * spinner arc traces.
- */
- public void setCenterRadius(double centerRadius) {
- mRingCenterRadius = centerRadius;
- }
-
- public double getCenterRadius() {
- return mRingCenterRadius;
- }
-
- /**
- * @param show Set to true to show the arrow head on the progress spinner.
- */
- public void setShowArrow(boolean show) {
- if (mShowArrow != show) {
- mShowArrow = show;
- invalidateSelf();
- }
- }
-
- /**
- * @param scale Set the scale of the arrowhead for the spinner.
- */
- public void setArrowScale(float scale) {
- if (scale != mArrowScale) {
- mArrowScale = scale;
- invalidateSelf();
- }
- }
-
- /**
- * @return The amount the progress spinner is currently rotated, between [0..1].
- */
- public float getStartingRotation() {
- return mStartingRotation;
- }
-
- /**
- * If the start / end trim are offset to begin with, store them so that
- * animation starts from that offset.
- */
- public void storeOriginals() {
- mStartingStartTrim = mStartTrim;
- mStartingEndTrim = mEndTrim;
- mStartingRotation = mRotation;
- }
-
- /**
- * Reset the progress spinner to default rotation, start and end angles.
- */
- public void resetOriginals() {
- mStartingStartTrim = 0;
- mStartingEndTrim = 0;
- mStartingRotation = 0;
- setStartTrim(0);
- setEndTrim(0);
- setRotation(0);
- }
-
- private void invalidateSelf() {
- mCallback.invalidateDrawable(null);
- }
- }
-}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/progresslayout/ProgressLayout.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/header/progresslayout/ProgressLayout.java
deleted file mode 100644
index f4e9330ea378e23cf5c0fbd70027b6fd7b2b136c..0000000000000000000000000000000000000000
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/header/progresslayout/ProgressLayout.java
+++ /dev/null
@@ -1,227 +0,0 @@
-package com.lcodecore.tkrefreshlayout.header.progresslayout;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.content.Context;
-import android.content.res.Resources;
-import android.support.annotation.ColorInt;
-import android.support.annotation.ColorRes;
-import android.support.v4.view.ViewCompat;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.Animation;
-import android.widget.FrameLayout;
-
-import com.lcodecore.tkrefreshlayout.IHeaderView;
-import com.lcodecore.tkrefreshlayout.OnAnimEndListener;
-
-/**
- * Created by lcodecore on 2016/11/27.
- */
-
-public class ProgressLayout extends FrameLayout implements IHeaderView {
- private int mCircleWidth;
- private int mCircleHeight;
- private static final int CIRCLE_DIAMETER = 40;
- private static final int CIRCLE_DIAMETER_LARGE = 56;
- // Maps to ProgressBar.Large style
- public static final int LARGE = MaterialProgressDrawable.LARGE;
- // Maps to ProgressBar default style
- public static final int DEFAULT = MaterialProgressDrawable.DEFAULT;
- // Default background for the progress spinner
- private static final int CIRCLE_BG_LIGHT = 0xFFFAFAFA;
- // Default offset in dips from the top of the view to where the progress spinner should stop
- private static final int DEFAULT_CIRCLE_TARGET = 64;
- private static final float MAX_PROGRESS_ANGLE = .8f;
-
- private static final int MAX_ALPHA = 255;
- private static final int STARTING_PROGRESS_ALPHA = (int) (.3f * MAX_ALPHA);
-
- private CircleImageView mCircleView;
- private MaterialProgressDrawable mProgress;
-
- public ProgressLayout(Context context) {
- this(context, null);
- }
-
- public ProgressLayout(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public ProgressLayout(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
-
- final DisplayMetrics metrics = getResources().getDisplayMetrics();
- mCircleWidth = (int) (CIRCLE_DIAMETER * metrics.density);
- mCircleHeight = (int) (CIRCLE_DIAMETER * metrics.density);
- createProgressView();
- ViewCompat.setChildrenDrawingOrderEnabled(this, true);
- // the absolute offset has to take into account that the circle starts at an offset
- }
-
- private void createProgressView() {
- mCircleView = new CircleImageView(getContext(), CIRCLE_BG_LIGHT, CIRCLE_DIAMETER / 2);
- mProgress = new MaterialProgressDrawable(getContext(), this);
- mProgress.setBackgroundColor(CIRCLE_BG_LIGHT);
- mCircleView.setImageDrawable(mProgress);
- mCircleView.setVisibility(View.GONE);
- LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
- mCircleView.setLayoutParams(params);
- addView(mCircleView);
- }
-
- /**
- * Set the background color of the progress spinner disc.
- *
- * @param colorRes Resource id of the color.
- */
- public void setProgressBackgroundColorSchemeResource(@ColorRes int colorRes) {
- setProgressBackgroundColorSchemeColor(getResources().getColor(colorRes));
- }
-
- /**
- * Set the background color of the progress spinner disc.
- *
- * @param color
- */
- public void setProgressBackgroundColorSchemeColor(@ColorInt int color) {
- mCircleView.setBackgroundColor(color);
- mProgress.setBackgroundColor(color);
- }
-
- /**
- * Set the color resources used in the progress animation from color resources.
- * The first color will also be the color of the bar that grows in response
- * to a user swipe gesture.
- *
- * @param colorResIds
- */
- public void setColorSchemeResources(@ColorRes int... colorResIds) {
- final Resources res = getResources();
- int[] colorRes = new int[colorResIds.length];
- for (int i = 0; i < colorResIds.length; i++) {
- colorRes[i] = res.getColor(colorResIds[i]);
- }
- setColorSchemeColors(colorRes);
- }
-
- /**
- * Set the colors used in the progress animation. The first
- * color will also be the color of the bar that grows in response to a user
- * swipe gesture.
- *
- * @param colors
- */
- public void setColorSchemeColors(int... colors) {
- mProgress.setColorSchemeColors(colors);
- }
-
- /**
- * One of DEFAULT, or LARGE.
- */
- public void setSize(int size) {
- if (size != MaterialProgressDrawable.LARGE && size != MaterialProgressDrawable.DEFAULT) {
- return;
- }
- final DisplayMetrics metrics = getResources().getDisplayMetrics();
- if (size == MaterialProgressDrawable.LARGE) {
- mCircleHeight = mCircleWidth = (int) (CIRCLE_DIAMETER_LARGE * metrics.density);
- } else {
- mCircleHeight = mCircleWidth = (int) (CIRCLE_DIAMETER * metrics.density);
- }
- // force the bounds of the progress circle inside the circle view to
- // update by setting it to null before updating its size and then
- // re-setting it
- mCircleView.setImageDrawable(null);
- mProgress.updateSizes(size);
- mCircleView.setImageDrawable(mProgress);
- }
-
- @Override
- public void reset() {
- mCircleView.clearAnimation();
- mProgress.stop();
- mCircleView.setVisibility(View.GONE);
-
- mCircleView.getBackground().setAlpha(MAX_ALPHA);
- mProgress.setAlpha(MAX_ALPHA);
- ViewCompat.setScaleX(mCircleView, 0);
- ViewCompat.setScaleY(mCircleView, 0);
- ViewCompat.setAlpha(mCircleView, 1);
- }
-
- @Override
- public View getView() {
- return this;
- }
-
- private boolean mIsBeingDragged = false;
-
- @Override
- public void onPullingDown(float fraction, float maxHeadHeight, float headHeight) {
- if (!mIsBeingDragged) {
- mIsBeingDragged = true;
- mProgress.setAlpha(STARTING_PROGRESS_ALPHA);
- }
-
- if (mCircleView.getVisibility() != View.VISIBLE) {
- mCircleView.setVisibility(View.VISIBLE);
- }
-
- if (fraction >= 1f) {
- ViewCompat.setScaleX(mCircleView, 1f);
- ViewCompat.setScaleY(mCircleView, 1f);
- } else {
- ViewCompat.setScaleX(mCircleView, fraction);
- ViewCompat.setScaleY(mCircleView, fraction);
- }
-
- if (fraction <= 1f) {
- mProgress.setAlpha((int) (STARTING_PROGRESS_ALPHA + (MAX_ALPHA - STARTING_PROGRESS_ALPHA) * fraction));
- }
-
- float adjustedPercent = (float) Math.max(fraction - .4, 0) * 5 / 3;
- float strokeStart = adjustedPercent * .8f;
- mProgress.setStartEndTrim(0f, Math.min(MAX_PROGRESS_ANGLE, strokeStart));
- mProgress.setArrowScale(Math.min(1f, adjustedPercent));
- float rotation = (-0.25f + .4f * adjustedPercent) * .5f;
- mProgress.setProgressRotation(rotation);
- }
-
- @Override
- public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) {
- mIsBeingDragged = false;
- if (fraction >= 1f) {
- ViewCompat.setScaleX(mCircleView, 1f);
- ViewCompat.setScaleY(mCircleView, 1f);
- } else {
- ViewCompat.setScaleX(mCircleView, fraction);
- ViewCompat.setScaleY(mCircleView, fraction);
- }
- }
-
- @Override
- public void startAnim(float maxHeadHeight, float headHeight) {
- mCircleView.setVisibility(View.VISIBLE);
- mCircleView.getBackground().setAlpha(MAX_ALPHA);
- mProgress.setAlpha(MAX_ALPHA);
- ViewCompat.setScaleX(mCircleView, 1f);
- ViewCompat.setScaleY(mCircleView, 1f);
- mProgress.setArrowScale(1f);
- mProgress.start();
- }
-
- @Override
- public void onFinish(final OnAnimEndListener animEndListener) {
- mCircleView.animate().scaleX(0).scaleY(0).alpha(0).setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- reset();
- animEndListener.onAnimEnd();
- }
- }).start();
- }
-}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/AVLoadingIndicatorView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/AVLoadingIndicatorView.java
new file mode 100644
index 0000000000000000000000000000000000000000..c9cd1b6ef038753222d7f37bb99d85dc2778dd4e
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/AVLoadingIndicatorView.java
@@ -0,0 +1,318 @@
+package com.lcodecore.tkrefreshlayout.processor;
+
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallBeatIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallClipRotateIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallClipRotateMultipleIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallClipRotatePulseIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallGridBeatIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallGridPulseIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallPulseIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallPulseRiseIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallPulseSyncIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallRotateIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallScaleIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallScaleMultipleIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallScaleRippleIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallScaleRippleMultipleIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallSpinFadeLoaderIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallTrianglePathIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallZigZagDeflectIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BallZigZagIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.BaseIndicatorController;
+import com.lcodecore.tkrefreshlayout.processor.indicator.CubeTransitionIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.LineScaleIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.LineScalePartyIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.LineScalePulseOutIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.LineScalePulseOutRapidIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.LineSpinFadeLoaderIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.PacmanIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.SemiCircleSpinIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.SquareSpinIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.SysProgressIndicator;
+import com.lcodecore.tkrefreshlayout.processor.indicator.TriangleSkewSpinIndicator;
+import com.lcodecore.tkrefreshlayout.utils.AttrUtils;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
+
+public class AVLoadingIndicatorView extends Component implements Component.DrawTask,
+ Component.BindStateChangedListener {
+ //indicators
+ public static final int SysProgress=-1;
+ public static final int BallPulse=0;
+ public static final int BallGridPulse=1;
+ public static final int BallClipRotate=2;
+ public static final int BallClipRotatePulse=3;
+ public static final int SquareSpin=4;
+ public static final int BallClipRotateMultiple=5;
+ public static final int BallPulseRise=6;
+ public static final int BallRotate=7;
+ public static final int CubeTransition=8;
+ public static final int BallZigZag=9;
+ public static final int BallZigZagDeflect=10;
+ public static final int BallTrianglePath=11;
+ public static final int BallScale=12;
+ public static final int LineScale=13;
+ public static final int LineScaleParty=14;
+ public static final int BallScaleMultiple=15;
+ public static final int BallPulseSync=16;
+ public static final int BallBeat=17;
+ public static final int LineScalePulseOut=18;
+ public static final int LineScalePulseOutRapid=19;
+ public static final int BallScaleRipple=20;
+ public static final int BallScaleRippleMultiple=21;
+ public static final int BallSpinFadeLoader=22;
+ public static final int LineSpinFadeLoader=23;
+ public static final int TriangleSkewSpin=24;
+ public static final int Pacman=25;
+ public static final int BallGridBeat=26;
+ public static final int SemiCircleSpin=27;
+
+ //Sizes (with defaults in DP)
+ public static final int DEFAULT_SIZE=30;
+
+ //attrs
+ private int mIndicatorId;
+ private int mIndicatorColor;
+ private boolean mHasAnimation = false;
+
+ private Paint mPaint;
+ private BaseIndicatorController mIndicatorController;
+
+
+ public AVLoadingIndicatorView(Context context) {
+ super(context);
+ init(context, null, null);
+ }
+
+ public AVLoadingIndicatorView(Context context, AttrSet attrSet) {
+ super(context, attrSet);
+ init(context, attrSet, null);
+
+ }
+
+ public AVLoadingIndicatorView(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ init(context, attrSet, styleName);
+ }
+
+ private void init(Context context, AttrSet attrSet, String styleName){
+ mIndicatorId = AttrUtils.getIntFromAttr(attrSet, "avl_indicator_int", BallGridPulse);
+ mIndicatorColor = AttrUtils.getColorFromAttr(attrSet, "avl_indicator_color", Color.WHITE.getValue());
+ mPaint=new Paint();
+
+ mPaint.setColor(new Color(mIndicatorColor));
+ mPaint.setStyle(Paint.Style.FILL_STYLE);
+ mPaint.setAntiAlias(true);
+ if (!mHasAnimation){
+ mHasAnimation=true;
+ applyAnimation();
+ }
+ applyIndicator();
+ setEstimateSizeListener(new EstimateSizeListener() {
+ @Override
+ public boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) {
+ int width =measureDimension(dp2px(DEFAULT_SIZE,getContext()),widthEstimateConfig);
+ int height =measureDimension(dp2px(DEFAULT_SIZE,getContext()),heightEstimateConfig);
+ setEstimatedSize(width,height);
+ return true;
+ }
+ });
+ addDrawTask(this);
+
+ }
+
+ public void setIndicatorId(int indicatorId){
+ mIndicatorId = indicatorId;
+ applyIndicator();
+ }
+
+ public void setIndicatorColor(int color){
+ mIndicatorColor = color;
+ mPaint.setColor(new Color(mIndicatorColor));
+ this.invalidate();
+ }
+
+
+
+ private void applyIndicator(){
+ switch (mIndicatorId){
+ case SysProgress:
+ mIndicatorController=new SysProgressIndicator();
+ break;
+ case BallPulse:
+ mIndicatorController=new BallPulseIndicator();
+ break;
+ case BallGridPulse:
+ mIndicatorController=new BallGridPulseIndicator();
+ break;
+ case BallClipRotate:
+ mIndicatorController=new BallClipRotateIndicator();
+ break;
+ case BallClipRotatePulse:
+ mIndicatorController=new BallClipRotatePulseIndicator();
+ break;
+ case SquareSpin:
+ mIndicatorController=new SquareSpinIndicator();
+ break;
+ case BallClipRotateMultiple:
+ mIndicatorController=new BallClipRotateMultipleIndicator();
+ break;
+ case BallPulseRise://待解决
+ mIndicatorController=new BallPulseRiseIndicator();
+ break;
+ case BallRotate:
+ mIndicatorController=new BallRotateIndicator();
+ break;
+ case CubeTransition://待解决
+ mIndicatorController=new CubeTransitionIndicator();
+ break;
+ case BallZigZag://待解决
+ mIndicatorController=new BallZigZagIndicator();
+ break;
+ case BallZigZagDeflect://待解决
+ mIndicatorController=new BallZigZagDeflectIndicator();
+ break;
+ case BallTrianglePath://待解决
+ mIndicatorController=new BallTrianglePathIndicator();
+ break;
+ case BallScale:
+ mIndicatorController=new BallScaleIndicator();
+ break;
+ case LineScale:
+ mIndicatorController=new LineScaleIndicator();
+ break;
+ case LineScaleParty:
+ mIndicatorController=new LineScalePartyIndicator();
+ break;
+ case BallScaleMultiple:
+ mIndicatorController=new BallScaleMultipleIndicator();
+ break;
+ case BallPulseSync:
+ mIndicatorController=new BallPulseSyncIndicator();
+ break;
+ case BallBeat:
+ mIndicatorController=new BallBeatIndicator();
+ break;
+ case LineScalePulseOut:
+ mIndicatorController=new LineScalePulseOutIndicator();
+ break;
+ case LineScalePulseOutRapid:
+ mIndicatorController=new LineScalePulseOutRapidIndicator();
+ break;
+ case BallScaleRipple:
+ mIndicatorController=new BallScaleRippleIndicator();
+ break;
+ case BallScaleRippleMultiple:
+ mIndicatorController=new BallScaleRippleMultipleIndicator();
+ break;
+ case BallSpinFadeLoader:
+ mIndicatorController=new BallSpinFadeLoaderIndicator();
+ break;
+ case LineSpinFadeLoader:
+ mIndicatorController=new LineSpinFadeLoaderIndicator();
+ break;
+ case TriangleSkewSpin:
+ mIndicatorController=new TriangleSkewSpinIndicator();
+ break;
+ case Pacman://待解决
+ mIndicatorController=new PacmanIndicator();
+ break;
+ case BallGridBeat:
+ mIndicatorController=new BallGridBeatIndicator();
+ break;
+ case SemiCircleSpin:
+ mIndicatorController=new SemiCircleSpinIndicator();
+ break;
+ default:
+ break;
+ }
+ mIndicatorController.setTarget(this);
+ }
+
+ private int measureDimension(int defaultSize, int measureSpec){
+ int result = defaultSize;
+ int specMode = EstimateSpec.getMode(measureSpec);
+ int specSize = EstimateSpec.getSize(measureSpec);
+ if (specMode == EstimateSpec.PRECISE) {
+ result = specSize;
+ } else if (specMode == EstimateSpec.NOT_EXCEED) {
+ result = Math.min(defaultSize, specSize);
+ } else {
+ result = defaultSize;
+ }
+ return result;
+ }
+
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ drawIndicator(canvas);
+ }
+
+ @Override
+ public void arrange(int left, int top, int width, int height) {
+ super.arrange(left, top, width, height);
+ if (!mHasAnimation){
+ mHasAnimation=true;
+ applyAnimation();
+ }
+ }
+
+ @Override
+ public void setVisibility(int visibility) {
+ if(getVisibility() != visibility){
+ super.setVisibility(visibility);
+ if(mIndicatorController == null)
+ return;
+ if(visibility == HIDE || visibility == INVISIBLE){
+ mIndicatorController.setAnimationStatus(BaseIndicatorController.AnimStatus.END);
+ }else {
+ mIndicatorController.setAnimationStatus(BaseIndicatorController.AnimStatus.START);
+ }
+ }
+ }
+
+ @Override
+ public void onComponentBoundToWindow(Component component) {
+ if(mIndicatorController == null)
+ return;
+ mIndicatorController.setAnimationStatus(BaseIndicatorController.AnimStatus.START);
+ }
+
+ @Override
+ public void onComponentUnboundFromWindow(Component component) {
+ if(mIndicatorController == null)
+ return;
+ mIndicatorController.setAnimationStatus(BaseIndicatorController.AnimStatus.CANCEL);
+ }
+
+ void drawIndicator(Canvas canvas){
+ if(mIndicatorController == null)
+ return;
+ mIndicatorController.draw(canvas, mPaint);
+ }
+
+
+ public void applyAnimation(){
+ if(mIndicatorController == null)
+ return;
+ mIndicatorController.initAnimation();
+ }
+ public void destroy(){
+ mHasAnimation = true;
+ if(mIndicatorController != null){
+ mIndicatorController.destroy();
+ mIndicatorController = null;
+ }
+ mPaint = null;
+ }
+
+ private final static float NORMAL_PIXEL_DENSITY = 160f;
+ private static int dp2px(float dp, Context context) {
+ float scale = context.getResourceManager().getDeviceCapability().screenDensity;
+ return (int)(dp*scale/NORMAL_PIXEL_DENSITY + 0.5f);
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/AnimProcessor.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/AnimProcessor.java
deleted file mode 100644
index a8ad5e206fca9bf7314019b52925a53788bc9a78..0000000000000000000000000000000000000000
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/AnimProcessor.java
+++ /dev/null
@@ -1,559 +0,0 @@
-package com.lcodecore.tkrefreshlayout.processor;
-
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.support.v7.widget.RecyclerView;
-import android.util.Log;
-import android.view.animation.DecelerateInterpolator;
-
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-import com.lcodecore.tkrefreshlayout.utils.LogUtil;
-import com.lcodecore.tkrefreshlayout.utils.ScrollingUtil;
-
-import java.util.LinkedList;
-
-import static android.view.View.GONE;
-import static android.view.View.VISIBLE;
-
-/**
- * Created by lcodecore on 2016/11/26.
- */
-
-public class AnimProcessor implements IAnimRefresh, IAnimOverScroll {
-
- private TwinklingRefreshLayout.CoContext cp;
- private static final float animFraction = 1f;
- //动画的变化率
- private DecelerateInterpolator decelerateInterpolator;
-
- public AnimProcessor(TwinklingRefreshLayout.CoContext coProcessor) {
- this.cp = coProcessor;
- decelerateInterpolator = new DecelerateInterpolator(8);
- }
-
- private boolean scrollHeadLocked = false;
- private boolean scrollBottomLocked = false;
-
- public void scrollHeadByMove(float moveY) {
- float offsetY = decelerateInterpolator.getInterpolation(moveY / cp.getMaxHeadHeight() / 2) * moveY / 2;
-
- //禁止下拉刷新时下拉不显示头部
- if (cp.isPureScrollModeOn() || (!cp.enableRefresh() && !cp.isOverScrollTopShow())) {
- if (cp.getHeader().getVisibility() != GONE) {
- cp.getHeader().setVisibility(GONE);
- }
- } else {
- if (cp.getHeader().getVisibility() != VISIBLE) {
- cp.getHeader().setVisibility(VISIBLE);
- }
- }
-
- if (scrollHeadLocked && cp.isEnableKeepIView()) {
- cp.getHeader().setTranslationY(offsetY - cp.getHeader().getLayoutParams().height);
- } else {
- cp.getHeader().setTranslationY(0);
- cp.getHeader().getLayoutParams().height = (int) Math.abs(offsetY);
- cp.getHeader().requestLayout();
- cp.onPullingDown(offsetY);
- }
-
- if (!cp.isOpenFloatRefresh()) {
- cp.getTargetView().setTranslationY(offsetY);
- translateExHead((int) offsetY);
- }
- }
-
- public void scrollBottomByMove(float moveY) {
- float offsetY = decelerateInterpolator.getInterpolation(moveY / cp.getMaxBottomHeight() / 2) * moveY / 2;
-
- if (cp.isPureScrollModeOn() || (!cp.enableLoadmore() && !cp.isOverScrollBottomShow())) {
- if (cp.getFooter().getVisibility() != GONE) {
- cp.getFooter().setVisibility(GONE);
- }
- } else {
- if (cp.getFooter().getVisibility() != VISIBLE) {
- cp.getFooter().setVisibility(VISIBLE);
- }
- }
-
- if (scrollBottomLocked && cp.isEnableKeepIView()) {
- cp.getFooter().setTranslationY(cp.getFooter().getLayoutParams().height - offsetY);
- } else {
- cp.getFooter().setTranslationY(0);
- cp.getFooter().getLayoutParams().height = (int) Math.abs(offsetY);
- cp.getFooter().requestLayout();
- cp.onPullingUp(-offsetY);
- }
-
- cp.getTargetView().setTranslationY(-offsetY);
- }
-
- public void dealPullDownRelease() {
- if (!cp.isPureScrollModeOn() && cp.enableRefresh() && getVisibleHeadHeight() >= cp.getHeadHeight() - cp.getTouchSlop()) {
- animHeadToRefresh();
- } else {
- animHeadBack(false);
- }
- }
-
- public void dealPullUpRelease() {
- if (!cp.isPureScrollModeOn() && cp.enableLoadmore() && getVisibleFootHeight() >= cp.getBottomHeight() - cp.getTouchSlop()) {
- animBottomToLoad();
- } else {
- animBottomBack(false);
- }
- }
-
- private int getVisibleHeadHeight() {
- LogUtil.i("header translationY:" + cp.getHeader().getTranslationY() + ",Visible head height:" + (cp.getHeader().getLayoutParams().height + cp.getHeader().getTranslationY()));
- return (int) (cp.getHeader().getLayoutParams().height + cp.getHeader().getTranslationY());
- }
-
- private int getVisibleFootHeight() {
- LogUtil.i("footer translationY:" + cp.getFooter().getTranslationY() + "");
- return (int) (cp.getFooter().getLayoutParams().height - cp.getFooter().getTranslationY());
- }
-
- private void transHeader(float offsetY) {
- cp.getHeader().setTranslationY(offsetY - cp.getHeader().getLayoutParams().height);
- }
-
- private void transFooter(float offsetY) {
- cp.getFooter().setTranslationY(cp.getFooter().getLayoutParams().height - offsetY);
- }
-
- private boolean isAnimHeadToRefresh = false;
-
- /**
- * 1.满足进入刷新的条件或者主动刷新时,把Head位移到刷新位置(当前位置 ~ HeadHeight)
- */
- public void animHeadToRefresh() {
- LogUtil.i("animHeadToRefresh:");
- isAnimHeadToRefresh = true;
- animLayoutByTime(getVisibleHeadHeight(), cp.getHeadHeight(), animHeadUpListener, new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
-
- isAnimHeadToRefresh = false;
-
- if (cp.getHeader().getVisibility() != VISIBLE) {
- cp.getHeader().setVisibility(VISIBLE);
- }
-
- cp.setRefreshVisible(true);
- if (cp.isEnableKeepIView()) {
- if (!scrollHeadLocked) {
- cp.setRefreshing(true);
- cp.onRefresh();
- scrollHeadLocked = true;
- }
- } else {
- cp.setRefreshing(true);
- cp.onRefresh();
- }
- }
- });
- }
-
- private boolean isAnimHeadBack = false;
-
- /**
- * 2.动画结束或不满足进入刷新状态的条件,收起头部(当前位置 ~ 0)
- */
- public void animHeadBack(final boolean isFinishRefresh) {
- LogUtil.i("animHeadBack:finishRefresh?->" + isFinishRefresh);
- isAnimHeadBack = true;
- if (isFinishRefresh && scrollHeadLocked && cp.isEnableKeepIView()) {
- cp.setPrepareFinishRefresh(true);
- }
- animLayoutByTime(getVisibleHeadHeight(), 0, animHeadUpListener, new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- isAnimHeadBack = false;
- cp.setRefreshVisible(false);
- if (isFinishRefresh && scrollHeadLocked && cp.isEnableKeepIView()) {
- cp.getHeader().getLayoutParams().height = 0;
- cp.getHeader().requestLayout();
- cp.getHeader().setTranslationY(0);
- scrollHeadLocked = false;
- cp.setRefreshing(false);
- cp.resetHeaderView();
- }
- }
- });
- }
-
- private boolean isAnimBottomToLoad = false;
-
- /**
- * 3.满足进入加载更多的条件或者主动加载更多时,把Footer移到加载更多位置(当前位置 ~ BottomHeight)
- */
- public void animBottomToLoad() {
- LogUtil.i("animBottomToLoad");
- isAnimBottomToLoad = true;
- animLayoutByTime(getVisibleFootHeight(), cp.getBottomHeight(), animBottomUpListener, new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- isAnimBottomToLoad = false;
-
- if (cp.getFooter().getVisibility() != VISIBLE) {
- cp.getFooter().setVisibility(VISIBLE);
- }
-
- cp.setLoadVisible(true);
- if (cp.isEnableKeepIView()) {
- if (!scrollBottomLocked) {
- cp.setLoadingMore(true);
- cp.onLoadMore();
- scrollBottomLocked = true;
- }
- } else {
- cp.setLoadingMore(true);
- cp.onLoadMore();
- }
- }
- });
- }
-
- private boolean isAnimBottomBack = false;
-
- /**
- * 4.加载更多完成或者不满足进入加载更多模式的条件时,收起尾部(当前位置 ~ 0)
- */
- public void animBottomBack(final boolean isFinishLoading) {
- LogUtil.i("animBottomBack:finishLoading?->" + isFinishLoading);
- isAnimBottomBack = true;
- if (isFinishLoading && scrollBottomLocked && cp.isEnableKeepIView()) {
- cp.setPrepareFinishLoadMore(true);
- }
- animLayoutByTime(getVisibleFootHeight(), 0, new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- int height = (int) animation.getAnimatedValue();
- //列表中加载到内容时滚动List
- if (!ScrollingUtil.isViewToBottom(cp.getTargetView(), cp.getTouchSlop())) {
- int dy = getVisibleFootHeight() - height;
- //可以让TargetView滚动dy高度,但这样两个方向上滚动感觉画面闪烁,改为dy/2是为了消除闪烁
- if (dy > 0) {
- if (cp.getTargetView() instanceof RecyclerView)
- ScrollingUtil.scrollAViewBy(cp.getTargetView(), dy);
- else ScrollingUtil.scrollAViewBy(cp.getTargetView(), dy / 2);
- }
- }
-
- //decorate the AnimatorUpdateListener
- animBottomUpListener.onAnimationUpdate(animation);
- }
- }, new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- isAnimBottomBack = false;
-
- cp.setLoadVisible(false);
- if (isFinishLoading) {
- if (scrollBottomLocked && cp.isEnableKeepIView()) {
- cp.getFooter().getLayoutParams().height = 0;
- cp.getFooter().requestLayout();
- cp.getFooter().setTranslationY(0);
- scrollBottomLocked = false;
- cp.resetBottomView();
- cp.setLoadingMore(false);
- }
- }
- }
- });
- }
-
- private boolean isAnimHeadHide = false;
-
- /**
- * 5.当刷新处于可见状态,向上滑动屏幕时,隐藏刷新控件
- *
- * @param vy 手指向上滑动速度
- */
- public void animHeadHideByVy(int vy) {
- if (isAnimHeadHide) return;
- isAnimHeadHide = true;
- LogUtil.i("animHeadHideByVy:vy->" + vy);
- vy = Math.abs(vy);
- if (vy < 5000) vy = 8000;
- animLayoutByTime(getVisibleHeadHeight(), 0, 5 * Math.abs(getVisibleHeadHeight() * 1000 / vy), animHeadUpListener, new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- isAnimHeadHide = false;
- cp.setRefreshVisible(false);
- if (!cp.isEnableKeepIView()) {
- cp.setRefreshing(false);
- cp.onRefreshCanceled();
- cp.resetHeaderView();
- }
- }
- });
- }
-
- private boolean isAnimBottomHide = false;
-
- /**
- * 6.当加载更多处于可见状态时,向下滑动屏幕,隐藏加载更多控件
- *
- * @param vy 手指向下滑动的速度
- */
- public void animBottomHideByVy(int vy) {
- LogUtil.i("animBottomHideByVy:vy->" + vy);
- if (isAnimBottomHide) return;
- isAnimBottomHide = true;
- vy = Math.abs(vy);
- if (vy < 5000) vy = 8000;
- animLayoutByTime(getVisibleFootHeight(), 0, 5 * getVisibleFootHeight() * 1000 / vy, animBottomUpListener, new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- isAnimBottomHide = false;
- cp.setLoadVisible(false);
- if (!cp.isEnableKeepIView()) {
- cp.setLoadingMore(false);
- cp.onLoadmoreCanceled();
- cp.resetBottomView();
- }
- }
- });
- }
-
- private boolean isAnimOsTop = false;
- private boolean isOverScrollTopLocked = false;
-
- /**
- * 7.执行顶部越界 To executive cross-border springback at the top.
- * 越界高度height ∝ vy/computeTimes,此处采用的模型是 height=A*(vy + B)/computeTimes
- *
- * @param vy 满足越界条件的手指滑动速度 the finger sliding speed on the screen.
- * @param computeTimes 从满足条件到滚动到顶部总共计算的次数 Calculation times from sliding to top.
- */
- public void animOverScrollTop(float vy, int computeTimes) {
- LogUtil.i("animOverScrollTop:vy->" + vy + ",computeTimes->" + computeTimes);
- if (isOverScrollTopLocked) return;
- isOverScrollTopLocked = true;
- isAnimOsTop = true;
- cp.setStatePTD();
- int oh = (int) Math.abs(vy / computeTimes / 2);
- final int overHeight = oh > cp.getOsHeight() ? cp.getOsHeight() : oh;
- final int time = overHeight <= 50 ? 115 : (int) (0.3 * overHeight + 100);
- animLayoutByTime(getVisibleHeadHeight(), overHeight, time, overScrollTopUpListener, new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- if (scrollHeadLocked && cp.isEnableKeepIView() && cp.showRefreshingWhenOverScroll()) {
- animHeadToRefresh();
- isAnimOsTop = false;
- isOverScrollTopLocked = false;
- return;
- }
- animLayoutByTime(overHeight, 0, 2 * time, overScrollTopUpListener, new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- isAnimOsTop = false;
- isOverScrollTopLocked = false;
- }
- });
- }
- });
- }
-
- private boolean isAnimOsBottom = false;
- private boolean isOverScrollBottomLocked = false;
-
- /**
- * 8.执行底部越界
- *
- * @param vy 满足越界条件的手指滑动速度
- * @param computeTimes 从满足条件到滚动到顶部总共计算的次数
- */
- public void animOverScrollBottom(float vy, int computeTimes) {
- LogUtil.i("animOverScrollBottom:vy->" + vy + ",computeTimes->" + computeTimes);
- if (isOverScrollBottomLocked) return;
- cp.setStatePBU();
- int oh = (int) Math.abs(vy / computeTimes / 2);
- final int overHeight = oh > cp.getOsHeight() ? cp.getOsHeight() : oh;
- final int time = overHeight <= 50 ? 115 : (int) (0.3 * overHeight + 100);
- if (!scrollBottomLocked && cp.autoLoadMore()) {
- cp.startLoadMore();
- } else {
- isOverScrollBottomLocked = true;
- isAnimOsBottom = true;
- animLayoutByTime(0, overHeight, time, overScrollBottomUpListener, new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- if (scrollBottomLocked && cp.isEnableKeepIView() && cp.showLoadingWhenOverScroll()) {
- animBottomToLoad();
- isAnimOsBottom = false;
- isOverScrollBottomLocked = false;
- return;
- }
- animLayoutByTime(overHeight, 0, 2 * time, overScrollBottomUpListener, new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- isAnimOsBottom = false;
- isOverScrollBottomLocked = false;
- }
- });
- }
- });
- }
- }
-
- private AnimatorUpdateListener animHeadUpListener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- int height = (int) animation.getAnimatedValue();
- if (scrollHeadLocked && cp.isEnableKeepIView()) {
- transHeader(height);
- } else {
- cp.getHeader().getLayoutParams().height = height;
- cp.getHeader().requestLayout();
- cp.getHeader().setTranslationY(0);
- cp.onPullDownReleasing(height);
- }
- if (!cp.isOpenFloatRefresh()) {
- cp.getTargetView().setTranslationY(height);
- translateExHead(height);
- }
- }
- };
-
- private AnimatorUpdateListener animBottomUpListener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- int height = (int) animation.getAnimatedValue();
- if (scrollBottomLocked && cp.isEnableKeepIView()) {
- transFooter(height);
- } else {
- cp.getFooter().getLayoutParams().height = height;
- cp.getFooter().requestLayout();
- cp.getFooter().setTranslationY(0);
- cp.onPullUpReleasing(height);
- }
- cp.getTargetView().setTranslationY(-height);
- }
- };
-
- private AnimatorUpdateListener overScrollTopUpListener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- int height = (int) animation.getAnimatedValue();
- if (cp.isOverScrollTopShow()) {
- if (cp.getHeader().getVisibility() != VISIBLE) {
- cp.getHeader().setVisibility(VISIBLE);
- }
- } else {
- if (cp.getHeader().getVisibility() != GONE) {
- cp.getHeader().setVisibility(GONE);
- }
- }
- if (scrollHeadLocked && cp.isEnableKeepIView()) {
- transHeader(height);
- } else {
- cp.getHeader().setTranslationY(0);
- cp.getHeader().getLayoutParams().height = height;
- cp.getHeader().requestLayout();
- cp.onPullDownReleasing(height);
- }
-
- cp.getTargetView().setTranslationY(height);
- translateExHead(height);
- }
- };
-
- private AnimatorUpdateListener overScrollBottomUpListener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- int height = (int) animation.getAnimatedValue();
- if (cp.isOverScrollBottomShow()) {
- if (cp.getFooter().getVisibility() != VISIBLE) {
- cp.getFooter().setVisibility(VISIBLE);
- }
- } else {
- if (cp.getFooter().getVisibility() != GONE) {
- cp.getFooter().setVisibility(GONE);
- }
- }
- if (scrollBottomLocked && cp.isEnableKeepIView()) {
- transFooter(height);
- } else {
- cp.getFooter().getLayoutParams().height = height;
- cp.getFooter().requestLayout();
- cp.getFooter().setTranslationY(0);
- cp.onPullUpReleasing(height);
- }
-
- cp.getTargetView().setTranslationY(-height);
- }
- };
-
- private void translateExHead(int offsetY) {
- if (!cp.isExHeadLocked()) cp.getExHead().setTranslationY(offsetY);
- }
-
- public void animLayoutByTime(int start, int end, long time, AnimatorUpdateListener listener, AnimatorListener animatorListener) {
- ValueAnimator va = ValueAnimator.ofInt(start, end);
- va.setInterpolator(new DecelerateInterpolator());
- va.addUpdateListener(listener);
- va.addListener(animatorListener);
- va.setDuration(time);
- va.start();
-// offerToQueue(va);
- }
-
- public void animLayoutByTime(int start, int end, long time, AnimatorUpdateListener listener) {
- ValueAnimator va = ValueAnimator.ofInt(start, end);
- va.setInterpolator(new DecelerateInterpolator());
- va.addUpdateListener(listener);
- va.setDuration(time);
- va.start();
-// offerToQueue(va);
- }
-
- public void animLayoutByTime(int start, int end, AnimatorUpdateListener listener, AnimatorListener animatorListener) {
- ValueAnimator va = ValueAnimator.ofInt(start, end);
- va.setInterpolator(new DecelerateInterpolator());
- va.addUpdateListener(listener);
- va.addListener(animatorListener);
- va.setDuration((int) (Math.abs(start - end) * animFraction));
- va.start();
-// offerToQueue(va);
- }
-
- //just for test.
- private void offerToQueue(Animator animator) {
- if (animator == null) return;
- if (animQueue == null) {
- animQueue = new LinkedList<>();
- }
- animQueue.offer(animator);
-
- System.out.println("Current Animators:" + animQueue.size());
-
- animator.addListener(new AnimatorListenerAdapter() {
- long startTime = 0;
-
- @Override
- public void onAnimationStart(Animator animation) {
- startTime = System.currentTimeMillis();
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- animQueue.poll();
- if (animQueue.size() > 0) {
- animQueue.getFirst().start();
- }
- System.out.println("Anim end:start time->" + startTime + ",elapsed time->" + (System.currentTimeMillis() - startTime));
- }
- });
- if (animQueue.size() == 1) {
- animator.start();
- }
- }
-
- private LinkedList animQueue;
-}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/Decorator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/Decorator.java
deleted file mode 100644
index 3270d1d856d4d1487e2dfc6db36718d66e5d9ec6..0000000000000000000000000000000000000000
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/Decorator.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.lcodecore.tkrefreshlayout.processor;
-
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-
-/**
- * Created by lcodecore on 2017/3/3.
- */
-
-public abstract class Decorator implements IDecorator {
- protected IDecorator decorator;
- protected TwinklingRefreshLayout.CoContext cp;
-
- public Decorator(TwinklingRefreshLayout.CoContext processor, IDecorator decorator1) {
- cp = processor;
- decorator = decorator1;
- }
-}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/IDecorator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/IDecorator.java
index 8c66e40f99cd40f30c6ca84e20abfdd1478596b4..6575e87d5478508d921dd8aea3339e87eb7a181a 100644
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/IDecorator.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/IDecorator.java
@@ -1,23 +1,23 @@
package com.lcodecore.tkrefreshlayout.processor;
-import android.view.MotionEvent;
+import ohos.multimodalinput.event.TouchEvent;
/**
* Created by lcodecore on 2017/3/1.
*/
public interface IDecorator {
- boolean dispatchTouchEvent(MotionEvent ev);
+ boolean dispatchTouchEvent(TouchEvent ev);
- boolean interceptTouchEvent(MotionEvent ev);
+ boolean interceptTouchEvent(TouchEvent ev);
- boolean dealTouchEvent(MotionEvent ev);
+ boolean dealTouchEvent(TouchEvent ev);
- void onFingerDown(MotionEvent ev);
+ void onFingerDown(TouchEvent ev);
- void onFingerUp(MotionEvent ev, boolean isFling);
+ void onFingerUp(TouchEvent ev, boolean isFling);
- void onFingerScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY, float velocityX, float velocityY);
+ void onFingerScroll(TouchEvent e1, TouchEvent e2, float distanceX, float distanceY, float velocityX, float velocityY);
- void onFingerFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
+ void onFingerFling(TouchEvent e1, TouchEvent e2, float velocityX, float velocityY);
}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/LVBase.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/LVBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ca07196817dbc670acb45b1edc575703802cafe
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/LVBase.java
@@ -0,0 +1,120 @@
+package com.lcodecore.tkrefreshlayout.processor;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.app.Context;
+
+import static ohos.agp.animation.Animator.CurveType.LINEAR;
+
+/**
+ * LVBase
+ *
+ * @since 2021-07-19
+ */
+public abstract class LVBase extends Component implements Animator.StateChangedListener, Animator.LoopedListener {
+ public static final int RESTART = 1;
+ public static final int INFINITE = -1;
+ public static final int REVERSE = 2;
+
+ public LVBase(Context context) {
+ this(context, null);
+ }
+
+ public LVBase(Context context, AttrSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public LVBase(Context context, AttrSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ InitPaint();
+ }
+
+ public void startAnim() {
+ stopAnim();
+ startViewAnim(0f, 1f, 500);
+ }
+
+ public void startAnim(int time) {
+ stopAnim();
+ startViewAnim(0f, 1f, time);
+ }
+
+ public void stopAnim() {
+ if (valueAnimator != null) {
+ createAnimatorProperty().reset();
+ valueAnimator.setLoopedCount(0);
+ valueAnimator.cancel();
+ valueAnimator.end();
+ if (OnStopAnim() == 0) {
+ valueAnimator.setLoopedCount(0);
+ valueAnimator.cancel();
+ valueAnimator.end();
+ }
+ }
+ }
+
+ public AnimatorValue valueAnimator;
+
+ private AnimatorValue startViewAnim(float startF, final float endF, long time) {
+ valueAnimator = new AnimatorValue();
+ valueAnimator.setDuration(time);
+ valueAnimator.setCurveType(LINEAR);
+ valueAnimator.setLoopedCount(SetAnimRepeatCount());
+
+ valueAnimator.setStateChangedListener(this);
+ valueAnimator.setLoopedListener(this);
+ valueAnimator.setValueUpdateListener((animatorValue, v) -> {
+ OnAnimationUpdate(animatorValue, v);
+ });
+
+ if (!valueAnimator.isRunning()) {
+ AinmIsRunning();
+ valueAnimator.start();
+ }
+
+ return valueAnimator;
+ }
+
+ protected abstract void InitPaint();
+
+ protected abstract void OnAnimationUpdate(AnimatorValue valueAnimator, float v);
+
+ protected abstract void OnAnimationRepeat(Animator animation);
+
+ protected abstract int OnStopAnim();
+
+ protected abstract int SetAnimRepeatCount();
+
+ protected abstract void AinmIsRunning();
+
+ @Override
+ public void onStart(Animator animator) {
+ }
+
+ @Override
+ public void onStop(Animator animator) {
+ }
+
+ @Override
+ public void onCancel(Animator animator) {
+ }
+
+ @Override
+ public void onEnd(Animator animator) {
+ }
+
+ @Override
+ public void onPause(Animator animator) {
+ }
+
+ @Override
+ public void onResume(Animator animator) {
+ }
+
+ @Override
+ public void onRepeat(Animator animator) {
+ OnAnimationRepeat(animator);
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/LVCircularZoom.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/LVCircularZoom.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b9c34ea40a148a0349aad41d6d7060114146f16
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/LVCircularZoom.java
@@ -0,0 +1,117 @@
+package com.lcodecore.tkrefreshlayout.processor;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
+
+public class LVCircularZoom extends LVBase implements Component.EstimateSizeListener, Component.DrawTask {
+
+ private Paint mPaint;
+
+ private float mWidth = 0f;
+ private float mHigh = 0f;
+ private float mMaxRadius = 16;
+ private int circularCount = 3;
+ private float mAnimatedValue = 1.0f;
+ private int mJumpValue = 0;
+
+ public LVCircularZoom(Context context) {
+ super(context);
+ }
+
+ public LVCircularZoom(Context context, AttrSet attrs) {
+ super(context, attrs);
+ }
+
+ public LVCircularZoom(Context context, AttrSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+
+ private void initPaint() {
+ addDrawTask(this);
+ setEstimateSizeListener(this);
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ mPaint.setStyle(Paint.Style.FILL_STYLE);
+ mPaint.setColor(Color.WHITE);
+ }
+
+
+ public void setViewColor(int color)
+ {
+ mPaint.setColor(new Color(color));
+ invalidate();
+ }
+
+
+ @Override
+ protected void OnAnimationRepeat(Animator animation) {
+ mJumpValue++;
+ }
+
+
+
+ @Override
+ protected int OnStopAnim() {
+ mAnimatedValue = 0f;
+ mJumpValue = 0;
+ return 0;
+ }
+ @Override
+ protected void InitPaint() {
+ initPaint();
+ }
+
+ @Override
+ protected void OnAnimationUpdate(AnimatorValue valueAnimator, float v) {
+ mAnimatedValue = v;
+ if (mAnimatedValue < 0.2) {
+ mAnimatedValue = 0.2f;
+ }
+ invalidate();
+ }
+
+
+ @Override
+ protected void AinmIsRunning() {
+
+ }
+ @Override
+ protected int SetAnimRepeatCount() {
+ return INFINITE;
+ }
+
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ float circularX = mWidth / circularCount;
+
+ for (int i = 0; i < circularCount; i++) {
+
+ if (i == mJumpValue % circularCount) {
+ canvas.drawCircle(i * circularX + circularX / 2f,
+ mHigh / 2,
+ mMaxRadius * mAnimatedValue, mPaint);
+
+
+ } else {
+ canvas.drawCircle(i * circularX + circularX / 2f,
+ mHigh / 2,
+ mMaxRadius, mPaint);
+ }
+
+ }
+ }
+
+ @Override
+ public boolean onEstimateSize(int i, int i1) {
+ mWidth = EstimateSpec.getSize(i);
+ mHigh = EstimateSpec.getSize(i1);
+ return false;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/OverScrollDecorator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/OverScrollDecorator.java
deleted file mode 100644
index edaf77bf10cede51006f9b1ce4b997bf9f03813f..0000000000000000000000000000000000000000
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/OverScrollDecorator.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package com.lcodecore.tkrefreshlayout.processor;
-
-import android.os.Handler;
-import android.os.Message;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-import com.lcodecore.tkrefreshlayout.utils.ScrollingUtil;
-
-/**
- * Created by lcodecore on 2017/3/1.
- */
-//TODO FullOverScrollDecorator、VerticalDecorator
-public class OverScrollDecorator extends Decorator {
-
- //主要为了监测Fling的动作,实现越界回弹
- private float mVelocityY;
-
- //满足越界的手势的最低速度(默认3000)
- private static final int OVER_SCROLL_MIN_VX = 3000;
-
- //针对View的延时策略
- private static final int MSG_START_COMPUTE_SCROLL = 0; //开始计算
- private static final int MSG_CONTINUE_COMPUTE_SCROLL = 1;//继续计算
- private static final int MSG_STOP_COMPUTE_SCROLL = 2; //停止计算
-
- private int cur_delay_times = 0; //当前计算次数
- private static final int ALL_DELAY_TIMES = 60; //10ms计算一次,总共计算20次
-
- public OverScrollDecorator(TwinklingRefreshLayout.CoContext processor, IDecorator decorator1) {
- super(processor, decorator1);
- }
-
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- return decorator != null && decorator.dispatchTouchEvent(ev);
- }
-
- @Override
- public boolean interceptTouchEvent(MotionEvent ev) {
- return decorator != null && decorator.interceptTouchEvent(ev);
- }
-
- @Override
- public boolean dealTouchEvent(MotionEvent e) {
- return decorator != null && decorator.dealTouchEvent(e);
- }
-
- private boolean preventTopOverScroll = false;
- private boolean preventBottomOverScroll = false;
- private boolean checkOverScroll = false;
-
- @Override
- public void onFingerDown(MotionEvent ev) {
- if (decorator != null) decorator.onFingerDown(ev);
- preventTopOverScroll = ScrollingUtil.isViewToTop(cp.getTargetView(), cp.getTouchSlop());
- preventBottomOverScroll = ScrollingUtil.isViewToBottom(cp.getTargetView(), cp.getTouchSlop());
- }
-
- @Override
- public void onFingerUp(MotionEvent ev, boolean isFling) {
-
- if (decorator != null) {
- decorator.onFingerUp(ev, checkOverScroll && isFling);
- }
- checkOverScroll = false;
- }
-
- @Override
- public void onFingerScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY, float velocityX, float velocityY) {
- if (decorator != null)
- decorator.onFingerScroll(e1, e2, distanceX, distanceY, velocityX, velocityY);
- }
-
- @Override
- public void onFingerFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- if (decorator != null) decorator.onFingerFling(e1, e2, velocityX, velocityY);
- //fling时才触发OverScroll,获取速度并采用演示策略估算View是否滚动到边界
- if (!cp.enableOverScroll()) return;
-
- int dy = (int) (e2.getY() - e1.getY());
- if (dy < -cp.getTouchSlop() && preventBottomOverScroll) return;//控件滚动在底部且向上fling
- if (dy > cp.getTouchSlop() && preventTopOverScroll) return;//控件滚动在顶部且向下fling
-
- mVelocityY = velocityY;
- if (Math.abs(mVelocityY) >= OVER_SCROLL_MIN_VX) {
- mHandler.sendEmptyMessage(MSG_START_COMPUTE_SCROLL);
- checkOverScroll = true;
- } else {
- mVelocityY = 0;
- cur_delay_times = ALL_DELAY_TIMES;
- }
- }
-
- private Handler mHandler = new Handler() {
-
- @Override
- public void handleMessage(Message msg) {
- int mTouchSlop = cp.getTouchSlop();
- switch (msg.what) {
- case MSG_START_COMPUTE_SCROLL:
- cur_delay_times = -1; //这里没有break,写作-1方便计数
- case MSG_CONTINUE_COMPUTE_SCROLL:
- cur_delay_times++;
-
- View mChildView = cp.getTargetView();
-
- if (cp.allowOverScroll()) {
- if (mVelocityY >= OVER_SCROLL_MIN_VX) {
- if (ScrollingUtil.isViewToTop(mChildView, mTouchSlop)) {
- cp.getAnimProcessor().animOverScrollTop(mVelocityY, cur_delay_times);
- mVelocityY = 0;
- cur_delay_times = ALL_DELAY_TIMES;
- }
- } else if (mVelocityY <= -OVER_SCROLL_MIN_VX) {
- if (ScrollingUtil.isViewToBottom(mChildView, mTouchSlop)) {
- cp.getAnimProcessor().animOverScrollBottom(mVelocityY, cur_delay_times);
- mVelocityY = 0;
- cur_delay_times = ALL_DELAY_TIMES;
- }
- }
- }
-
- //计算未超时,继续发送消息并循环计算
- if (cur_delay_times < ALL_DELAY_TIMES)
- mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_COMPUTE_SCROLL, 10);
- break;
- case MSG_STOP_COMPUTE_SCROLL:
- cur_delay_times = ALL_DELAY_TIMES;
- break;
- }
- }
- };
-}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/RefreshProcessor.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/RefreshProcessor.java
deleted file mode 100644
index b0f06a0c45e92e448934103e414f11c13ddb9278..0000000000000000000000000000000000000000
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/RefreshProcessor.java
+++ /dev/null
@@ -1,171 +0,0 @@
-package com.lcodecore.tkrefreshlayout.processor;
-
-import android.view.MotionEvent;
-import android.view.ViewConfiguration;
-
-import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
-import com.lcodecore.tkrefreshlayout.utils.ScrollingUtil;
-
-/**
- * Created by lcodecore on 2017/3/1.
- */
-
-public class RefreshProcessor implements IDecorator {
-
- protected TwinklingRefreshLayout.CoContext cp;
-
- public RefreshProcessor(TwinklingRefreshLayout.CoContext processor) {
- if (processor == null) throw new NullPointerException("The coprocessor can not be null.");
- cp = processor;
- }
-
- private float mTouchX, mTouchY;
- private boolean intercepted = false;
- private boolean willAnimHead = false;
- private boolean willAnimBottom = false;
- private boolean downEventSent = false;
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN:
- downEventSent = false;
- intercepted = false;
- mTouchX = ev.getX();
- mTouchY = ev.getY();
-
- if (cp.isEnableKeepIView()) {
- if (!cp.isRefreshing()) {
- cp.setPrepareFinishRefresh(false);
- }
- if (!cp.isLoadingMore()) {
- cp.setPrepareFinishLoadMore(false);
- }
- }
-
- cp.dispatchTouchEventSuper(ev);
- return true;
- case MotionEvent.ACTION_MOVE:
- mLastMoveEvent = ev;
- float dx = ev.getX() - mTouchX;
- float dy = ev.getY() - mTouchY;
- if (!intercepted && Math.abs(dx) <= Math.abs(dy) && Math.abs(dy) > cp.getTouchSlop()) {//滑动允许最大角度为45度
- if (dy > 0 && ScrollingUtil.isViewToTop(cp.getTargetView(), cp.getTouchSlop()) && cp.allowPullDown()) {
- cp.setStatePTD();
- mTouchX = ev.getX();
- mTouchY = ev.getY();
- sendCancelEvent();
- intercepted = true;
- return true;
- } else if (dy < 0 && ScrollingUtil.isViewToBottom(cp.getTargetView(), cp.getTouchSlop()) && cp.allowPullUp()) {
- cp.setStatePBU();
- mTouchX = ev.getX();
- mTouchY = ev.getY();
- intercepted = true;
- sendCancelEvent();
- return true;
- }
- }
- if (intercepted) {
- if (cp.isRefreshVisible() || cp.isLoadingVisible()) {
- return cp.dispatchTouchEventSuper(ev);
- }
- if (!cp.isPrepareFinishRefresh() && cp.isStatePTD()) {
- if (dy < -cp.getTouchSlop() || !ScrollingUtil.isViewToTop(cp.getTargetView(), cp.getTouchSlop())) {
- cp.dispatchTouchEventSuper(ev);
- }
- dy = Math.min(cp.getMaxHeadHeight() * 2, dy);
- dy = Math.max(0, dy);
- cp.getAnimProcessor().scrollHeadByMove(dy);
- } else if (!cp.isPrepareFinishLoadMore() && cp.isStatePBU()) {
- //加载更多的动作
- if (dy > cp.getTouchSlop() || !ScrollingUtil.isViewToBottom(cp.getTargetView(), cp.getTouchSlop())) {
- cp.dispatchTouchEventSuper(ev);
- }
- dy = Math.max(-cp.getMaxBottomHeight() * 2, dy);
- dy = Math.min(0, dy);
- cp.getAnimProcessor().scrollBottomByMove(Math.abs(dy));
- }
- if (dy == 0 && !downEventSent) {
- downEventSent = true;
- sendDownEvent();
- }
- return true;
- }
- break;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- if (intercepted) {
- if (cp.isStatePTD()) {
- willAnimHead = true;
- } else if (cp.isStatePBU()) {
- willAnimBottom = true;
- }
- intercepted = false;
- return true;
- }
- break;
- }
- return cp.dispatchTouchEventSuper(ev);
- }
-
- private MotionEvent mLastMoveEvent;
-
- //发送cancel事件解决selection问题
- private void sendCancelEvent() {
- if (mLastMoveEvent == null) {
- return;
- }
- MotionEvent last = mLastMoveEvent;
- MotionEvent e = MotionEvent.obtain(last.getDownTime(), last.getEventTime() + ViewConfiguration.getLongPressTimeout(), MotionEvent.ACTION_CANCEL, last.getX(), last.getY(), last.getMetaState());
- cp.dispatchTouchEventSuper(e);
- }
-
- private void sendDownEvent() {
- final MotionEvent last = mLastMoveEvent;
- MotionEvent e = MotionEvent.obtain(last.getDownTime(), last.getEventTime(), MotionEvent.ACTION_DOWN, last.getX(), last.getY(), last.getMetaState());
- cp.dispatchTouchEventSuper(e);
- }
-
- @Override
- public boolean interceptTouchEvent(MotionEvent ev) {
- return false;
- }
-
- @Override
- public boolean dealTouchEvent(MotionEvent e) {
- return false;
- }
-
- @Override
- public void onFingerDown(MotionEvent ev) {
- }
-
- @Override
- public void onFingerUp(MotionEvent ev, boolean isFling) {
- if (!isFling && willAnimHead) {
- cp.getAnimProcessor().dealPullDownRelease();
- }
- if (!isFling && willAnimBottom) {
- cp.getAnimProcessor().dealPullUpRelease();
- }
- willAnimHead = false;
- willAnimBottom = false;
- }
-
- @Override
- public void onFingerScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY, float velocityX, float velocityY) {
- //手指在屏幕上滚动,如果此时正处在刷新状态,可隐藏
- int mTouchSlop = cp.getTouchSlop();
- if (cp.isRefreshVisible() && distanceY >= mTouchSlop && !cp.isOpenFloatRefresh()) {
- cp.getAnimProcessor().animHeadHideByVy((int) velocityY);
- }
- if (cp.isLoadingVisible() && distanceY <= -mTouchSlop) {
- cp.getAnimProcessor().animBottomHideByVy((int) velocityY);
- }
- }
-
- @Override
- public void onFingerFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- }
-}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallBeatIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallBeatIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..c1b2031e386c8c418a33fa9c1babf131f6414864
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallBeatIndicator.java
@@ -0,0 +1,61 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallBeatIndicator extends BaseIndicatorController {
+ public static final float SCALE=1.0f;
+
+ public static final int ALPHA=255;
+
+ private float[] scaleFloats=new float[]{SCALE,
+ SCALE,
+ SCALE};
+
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float circleSpacing = 4.0f;
+ float radius = (getWidth() - circleSpacing * 2.0f) / 6.0f;
+ float x = getWidth() / 2.0f - (radius * 2.0f + circleSpacing);
+ float y = getHeight() / 2.0f;
+ for (int i = 0; i < 3; i++) {
+ canvas.save();
+ float translateX = x + (radius * 2.0f) * i + circleSpacing * i;
+ canvas.translate(translateX, y);
+ canvas.scale(scaleFloats[i], scaleFloats[i]);
+ canvas.drawCircle(0, 0, radius, paint);
+ canvas.restore();
+ }
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ int[] delays=new int[]{350,0,350};
+ for (int i = 0; i < 3; i++) {
+ final int index=i;
+ AnimatorValue scaleAnim= new AnimatorValue();
+ scaleAnim.setDuration(700);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setDelay(delays[i]);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloats[index] = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+
+
+ animators.add(scaleAnim);
+
+ }
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallClipRotateIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallClipRotateIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..304d27aa7b00ab5a5a681e9918030879db63c6c8
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallClipRotateIndicator.java
@@ -0,0 +1,64 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import com.lcodecore.tkrefreshlayout.utils.DeviceUtils;
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Arc;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.RectFloat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallClipRotateIndicator extends BaseIndicatorController {
+ private float scaleFloat=1;
+ private float degrees;
+ private Arc mArc = new Arc();//弧度
+
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ paint.setStyle(Paint.Style.STROKE_STYLE);
+ paint.setStrokeWidth(DeviceUtils.dp2px(getTarget().getContext(),1));
+ float x = (getWidth()) / 3.0f;
+ float y = (getHeight()) / 3.0f;
+ canvas.translate(x, y);
+ canvas.scale(scaleFloat, scaleFloat);
+ canvas.rotate(degrees * 360,0,0);
+ RectFloat rectF = new RectFloat(-x,- y + 5.0f,
+ x,y);
+ mArc.setArc( 0, 270, false);
+ canvas.drawArc(rectF,mArc,paint);
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(750);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloat = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+
+ AnimatorValue rotateAnim = new AnimatorValue();
+ rotateAnim.setDuration(750);
+ rotateAnim.setLoopedCount(-1);
+ rotateAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ degrees = v;
+ postInvalidate();
+ }
+ });
+ rotateAnim.start();
+ animators.add(scaleAnim);
+ animators.add(rotateAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallClipRotateMultipleIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallClipRotateMultipleIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..20d3cabcccf03db7f342a34a195c8f73be9d38e8
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallClipRotateMultipleIndicator.java
@@ -0,0 +1,85 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Arc;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.RectFloat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallClipRotateMultipleIndicator extends BaseIndicatorController {
+
+ private float scaleFloat=1;
+ private float degrees;
+
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ paint.setStrokeWidth(3);
+ paint.setStyle(Paint.Style.STROKE_STYLE);
+ float circleSpacing = 12;
+ float x = getWidth() / 2.0f;
+ float y = getHeight() / 2.0f;
+
+ canvas.save();
+
+ canvas.translate(x, y);
+ canvas.scale(scaleFloat, scaleFloat);
+ canvas.rotate(degrees * 360,0,0);
+ //draw two big arc
+ float[] bStartAngles = new float[]{135,-45};
+ for (int i = 0; i < 2; i++) {
+ RectFloat rectF=new RectFloat(-x + circleSpacing,-y + circleSpacing,x-circleSpacing,y-circleSpacing);
+ Arc arc = new Arc();
+ arc.setArc(bStartAngles[i], 90, false);
+ canvas.drawArc(rectF,arc , paint);
+ }
+
+ canvas.restore();
+ canvas.translate(x, y);
+ canvas.scale(scaleFloat, scaleFloat);
+ canvas.rotate(-degrees*360,0,0);
+ //draw two small arc
+ float[] sStartAngles=new float[]{225,45};
+ for (int i = 0; i < 2; i++) {
+ RectFloat rectF=new RectFloat(-x/1.8f+circleSpacing,-y/1.8f+circleSpacing,x/1.8f-circleSpacing,y/1.8f-circleSpacing);
+ Arc arc = new Arc();
+ arc.setArc(sStartAngles[i], 90, false);
+ canvas.drawArc(rectF,arc , paint);
+ }
+
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(1000);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloat = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+
+ AnimatorValue rotateAnim = new AnimatorValue();
+ rotateAnim.setDuration(1000);
+ rotateAnim.setLoopedCount(-1);
+ rotateAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ degrees = v;
+ postInvalidate();
+ }
+ });
+ rotateAnim.start();
+ animators.add(scaleAnim);
+ animators.add(rotateAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallClipRotatePulseIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallClipRotatePulseIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a58383148942b05b38c3242fbd9e628edd025da
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallClipRotatePulseIndicator.java
@@ -0,0 +1,92 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Arc;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.RectFloat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallClipRotatePulseIndicator extends BaseIndicatorController {
+
+ private float scaleFloat1;
+ private float scaleFloat2;
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float circleSpacing=12;
+ float x=getWidth()/2.0f;
+ float y=getHeight()/2.0f;
+
+ //draw fill circle
+ canvas.save();
+ canvas.translate(x, y);
+ canvas.scale(scaleFloat1, scaleFloat1);
+ paint.setStyle(Paint.Style.FILL_STYLE);
+ canvas.drawCircle(0, 0, x / 2.5f, paint);
+
+ canvas.restore();
+
+ canvas.translate(x, y);
+ canvas.scale(scaleFloat2, scaleFloat2);
+
+ paint.setStrokeWidth(3);
+ paint.setStyle(Paint.Style.STROKE_STYLE);
+
+ //draw two arc
+ float[] startAngles=new float[]{225,45};
+ for (int i = 0; i < 2; i++) {
+ RectFloat rectF=new RectFloat(-x+circleSpacing,-y+circleSpacing,x-circleSpacing,y-circleSpacing);
+ Arc arc = new Arc();
+ arc.setArc(startAngles[i], 90, false);
+ canvas.drawArc(rectF,arc , paint);
+ }
+ }
+
+ @Override
+ public List createAnimation() {
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(1000);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloat1 = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+
+ AnimatorValue scaleAnim2 = new AnimatorValue();
+ scaleAnim2.setDuration(1000);
+ scaleAnim2.setLoopedCount(-1);
+ scaleAnim2.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloat2 = v;
+ getTarget().setRotation(v*360);
+ postInvalidate();
+ }
+ });
+ scaleAnim2.start();
+
+ AnimatorValue rotateAnim = new AnimatorValue();
+ rotateAnim.setDuration(1000);
+ rotateAnim.setLoopedCount(-1);
+ rotateAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ postInvalidate();
+ }
+ });
+ rotateAnim.start();
+
+ List animators=new ArrayList<>();
+ animators.add(scaleAnim);
+ animators.add(scaleAnim2);
+ animators.add(rotateAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallGridBeatIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallGridBeatIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e63ac5e5404d2a0620916bf8935069011fb3db4
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallGridBeatIndicator.java
@@ -0,0 +1,71 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallGridBeatIndicator extends BaseIndicatorController {
+
+ public static final int ALPHA=255;
+
+ int[] alphas=new int[]{ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA};
+
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float circleSpacing=4;
+ float radius=(getWidth()-circleSpacing*4)/6;
+ float x = getWidth()/ 2.0f-(radius*2.0f+circleSpacing);
+ float y = getWidth()/ 2.0f-(radius*2.0f+circleSpacing);
+
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ canvas.save();
+ float translateX=x+(radius*2)*j+circleSpacing*j;
+ float translateY=y+(radius*2)*i+circleSpacing*i;
+ canvas.translate(translateX, translateY);
+// paint.setAlpha(alphas[3 * i + j]);
+ canvas.drawCircle(0, 0, radius, paint);
+ canvas.restore();
+ }
+ }
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+
+ int[] durations={960, 930, 1190, 1130, 1340, 940, 1200, 820, 1190};
+ int[] delays= {360, 400, 680, 410, 710, -150, -120, 10, 320};
+
+ for (int i = 0; i < 9; i++) {
+ final int index=i;
+ AnimatorValue alphaAnim = new AnimatorValue();
+ alphaAnim.setDuration(durations[i]);
+ alphaAnim.setLoopedCount(-1);
+ alphaAnim.setDelay(delays[i]);
+ alphaAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ alphas[index] = (int) v*255;
+ postInvalidate();
+ }
+ });
+
+ alphaAnim.start();
+ animators.add(alphaAnim);
+ }
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallGridPulseIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallGridPulseIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..66c713007ae7458d425e615b3de194866a7e9605
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallGridPulseIndicator.java
@@ -0,0 +1,96 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallGridPulseIndicator extends BaseIndicatorController {
+ public static final int ALPHA=255;
+
+ public static final float SCALE=1.0f;
+
+ int[] alphas=new int[]{ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA};
+
+ float[] scaleFloats=new float[]{SCALE,
+ SCALE,
+ SCALE,
+ SCALE,
+ SCALE,
+ SCALE,
+ SCALE,
+ SCALE,
+ SCALE};
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float circleSpacing = 4;
+ float radius = (getWidth() - circleSpacing * 4) / 6;
+ float x = getWidth() / 2.0f - (radius * 2 + circleSpacing);
+ float y = getWidth() / 2.0f - (radius * 2 + circleSpacing);
+
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ canvas.save();
+ float translateX=x+(radius*2)*j+circleSpacing*j;
+ float translateY=y+(radius*2)*i+circleSpacing*i;
+ canvas.translate(translateX, translateY);
+ canvas.scale(scaleFloats[3 * i + j], scaleFloats[3 * i + j]);
+ paint.setAlpha(alphas[3 * i + j]);
+ canvas.drawCircle(0, 0, radius, paint);
+ canvas.restore();
+ }
+ }
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ int[] durations={720, 1020, 1280, 1420, 1450, 1180, 870, 1450, 1060};
+ int[] delays= {-60, 250, -170, 480, 310, 30, 460, 780, 450};
+
+ for (int i = 0; i < 9; i++) {
+ final int index=i;
+
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(durations[i]);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setDelay(delays[i]);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloats[index] = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+
+ AnimatorValue alphaAnim = new AnimatorValue();
+ alphaAnim.setDelay(delays[i]);
+ alphaAnim.setDuration(durations[i]);
+ alphaAnim.setLoopedCount(-1);
+ alphaAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+// alphas[index] = (int)v;
+ postInvalidate();
+ }
+ });
+
+ alphaAnim.start();
+ animators.add(scaleAnim);
+ animators.add(alphaAnim);
+ }
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallPulseIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallPulseIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..64e5f87411cf34706678aedc6003e28f6785c07d
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallPulseIndicator.java
@@ -0,0 +1,56 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallPulseIndicator extends BaseIndicatorController{
+ public static final float SCALE=1.0f;
+ private float[] scaleFloats=new float[]{SCALE,
+ SCALE,
+ SCALE};
+
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float circleSpacing=4;
+ float radius=(Math.min(getWidth(),getHeight())-circleSpacing*2)/7;
+ float x = getWidth()/ 2.0f -(radius*2+circleSpacing);
+ float y = getHeight() / 2.0f;
+ 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, paint);
+ canvas.restore();
+
+ }
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ int[] delays=new int[]{120,240,360};
+ for (int i = 0; i < 3; i++) {
+ final int index=i;
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(1000);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setDelay(delays[i]);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloats[index] = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ }
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallPulseRiseIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallPulseRiseIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..c78ac8e3465efd366ff341c1ef66dc19747444fb
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallPulseRiseIndicator.java
@@ -0,0 +1,39 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallPulseRiseIndicator extends BaseIndicatorController {
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float radius=getWidth()/10.0f;
+ canvas.drawCircle(getWidth()/4.0f,radius*2,radius,paint);
+ canvas.drawCircle(getWidth()*3/4.0f,radius*2,radius,paint);
+
+ canvas.drawCircle(radius,getHeight()-2*radius,radius,paint);
+ canvas.drawCircle(getWidth()/2.0f,getHeight()-2*radius,radius,paint);
+ canvas.drawCircle(getWidth()-radius,getHeight()-2*radius,radius,paint);
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setLoopedCount(2500);
+ scaleAnim.setCurveType(Animator.CurveType.LINEAR);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ getTarget().setRotation(v);
+ }
+ });
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallPulseSyncIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallPulseSyncIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..844e94164cd43276c4d4e00fe082d40d81074a6a
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallPulseSyncIndicator.java
@@ -0,0 +1,51 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallPulseSyncIndicator extends BaseIndicatorController {
+ private float[] translateYFloats=new float[3];
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float circleSpacing=4;
+ float radius=(getWidth()-circleSpacing*2)/7;
+
+ float x = getWidth()/ 2.0f-(radius*2+circleSpacing);
+ for (int i = 0; i < 3; i++) {
+ canvas.save();
+ float translateX=x+(radius*2)*i+circleSpacing*i;
+ canvas.translate(translateX, translateYFloats[i]*15);
+ canvas.drawCircle(0, getHeight()/2.0f, radius, paint);
+ canvas.restore();
+ }
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ int[] delays=new int[]{70,140,210};
+ for (int i = 0; i < 3; i++) {
+ final int index=i;
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDelay(delays[i]);
+ scaleAnim.setDuration(600);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ translateYFloats[index] = v;
+ postInvalidate();
+ }
+ });
+
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ }
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallRotateIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallRotateIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf9ee53d5f006283361fa3a320be227491d54ea4
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallRotateIndicator.java
@@ -0,0 +1,54 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallRotateIndicator extends BaseIndicatorController{
+ private float scaleFloat=0.5f;
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float radius=getWidth()/10.0f;
+ float x = getWidth()/ 2.0f;
+ float y=getHeight()/2.0f;
+
+ canvas.save();
+ canvas.translate(x - radius * 2 - radius, y);
+ canvas.scale(scaleFloat, scaleFloat);
+ canvas.drawCircle(0, 0, radius, paint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(x, y);
+ canvas.scale(scaleFloat, scaleFloat);
+ canvas.drawCircle(0, 0, radius, paint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(x + radius * 2 + radius, y);
+ canvas.scale(scaleFloat, scaleFloat);
+ canvas.drawCircle(0,0,radius, paint);
+ canvas.restore();
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setDuration(1500);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ getTarget().setRotation(v*360);
+ }
+ });
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallScaleIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallScaleIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..472022a7a986f2c0ae99d44fa7da360396e44b84
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallScaleIndicator.java
@@ -0,0 +1,43 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallScaleIndicator extends BaseIndicatorController {
+ float scale = 1;
+
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float circleSpacing=4;
+
+ canvas.scale(scale,scale,getWidth()/2.0f,getHeight()/2.0f);
+ paint.setAlpha(120);
+ canvas.drawCircle(getWidth()/2.0f,getHeight()/2.0f,getWidth()/3.0f-circleSpacing,paint);
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(1200);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setCurveType(Animator.CurveType.SMOOTH_STEP);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scale = v;
+ postInvalidate();
+ }
+ });
+
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ return animators;
+ }
+}
+
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallScaleMultipleIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallScaleMultipleIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c22f5f83e58612431ce643e984e5f7ade890d2a
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallScaleMultipleIndicator.java
@@ -0,0 +1,64 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallScaleMultipleIndicator extends BaseIndicatorController {
+ float[] scaleFloats=new float[]{1,1,1};
+ int[] alphaInts=new int[]{255,255,255};
+
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float circleSpacing=4;
+ for (int i = 0; i < 3; i++) {
+// paint.setAlpha(alphaInts[i]);
+ canvas.scale(scaleFloats[i],scaleFloats[i],getWidth()/2.0f,getHeight()/2.0f);
+ canvas.drawCircle(getWidth()/2.0f,getHeight()/2.0f,getWidth()/2.0f-circleSpacing,paint);
+ }
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ long[] delays=new long[]{0, 200, 400};
+ for (int i = 0; i < 3; i++) {
+ final int index=i;
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setCurveType(Animator.CurveType.SMOOTH_STEP);
+ scaleAnim.setDuration(1000);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloats[index] = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+
+ AnimatorValue alphaAnim = new AnimatorValue();
+ alphaAnim.setCurveType(Animator.CurveType.SMOOTH_STEP);
+ alphaAnim.setLoopedCount(-1);
+ alphaAnim.setDuration(1000);
+ scaleAnim.setDelay(delays[i]);
+ alphaAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ alphaInts[index] = (int)v;
+ postInvalidate();
+ }
+ });
+
+ alphaAnim.start();
+
+ animators.add(scaleAnim);
+ animators.add(alphaAnim);
+ }
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallScaleRippleIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallScaleRippleIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a94be9468923aee29810153cfff2ac8367213e1
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallScaleRippleIndicator.java
@@ -0,0 +1,50 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallScaleRippleIndicator extends BallScaleIndicator {
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ paint.setStyle(Paint.Style.STROKE_STYLE);
+ paint.setStrokeWidth(3);
+ super.draw(canvas, paint);
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setCurveType(Animator.CurveType.SMOOTH_STEP);
+ scaleAnim.setDuration(1000);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scale =v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+
+ AnimatorValue alphaAnim = new AnimatorValue();
+ alphaAnim.setCurveType(Animator.CurveType.SMOOTH_STEP);
+ alphaAnim.setDuration(1000);
+ alphaAnim.setLoopedCount(-1);
+ alphaAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ postInvalidate();
+ }
+ });
+ alphaAnim.start();
+ animators.add(scaleAnim);
+ animators.add(alphaAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallScaleRippleMultipleIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallScaleRippleMultipleIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f5dae09e9e70ab85991c08788cccbab362752a1
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallScaleRippleMultipleIndicator.java
@@ -0,0 +1,57 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallScaleRippleMultipleIndicator extends BallScaleMultipleIndicator {
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ paint.setStyle(Paint.Style.STROKE_STYLE);
+ paint.setStrokeWidth(3);
+ super.draw(canvas, paint);
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ long[] delays=new long[]{0, 200, 400};
+ for (int i = 0; i < 3; i++) {
+ final int index=i;
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setCurveType(Animator.CurveType.SMOOTH_STEP);
+ scaleAnim.setDelay(delays[i]);
+ scaleAnim.setDuration(1000);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloats[index] = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+
+ AnimatorValue alphaAnim = new AnimatorValue();
+ alphaAnim.setCurveType(Animator.CurveType.SMOOTH_STEP);
+ alphaAnim.setLoopedCount(-1);
+ alphaAnim.setDuration(1000);
+ alphaAnim.setDelay(delays[i]);
+ alphaAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ alphaInts[index] = (int)v;
+ postInvalidate();
+ }
+ });
+ alphaAnim.start();
+ animators.add(scaleAnim);
+ animators.add(alphaAnim);
+ }
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallSpinFadeLoaderIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallSpinFadeLoaderIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..0bd9356864325244e9f72ddfd42bc9bb6745067f
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallSpinFadeLoaderIndicator.java
@@ -0,0 +1,101 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallSpinFadeLoaderIndicator extends BaseIndicatorController {
+
+ public static final float SCALE = 1.0f;
+
+ public static final int ALPHA = 255;
+
+ float[] scaleFloats = new float[]{SCALE,
+ SCALE,
+ SCALE,
+ SCALE,
+ SCALE,
+ SCALE,
+ SCALE,
+ SCALE};
+
+ int[] alphas = new int[]{ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA,
+ ALPHA};
+
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float radius = getWidth() / 10.0f;
+ for (int i = 0; i < 8; i++) {
+ canvas.save();
+ Point point = circleAt(getWidth(), getHeight(), getWidth() / 2.0f - radius, i * (Math.PI / 4.0f));
+ canvas.translate(point.x, point.y);
+ canvas.scale(scaleFloats[i], scaleFloats[i]);
+// paint.setAlpha(alphas[i]);
+ canvas.drawCircle(0, 0, radius, paint);
+ canvas.restore();
+ }
+ }
+
+ Point circleAt(int width, int height, float radius, double angle) {
+ float x = (float) (width / 2.0f + radius * (Math.cos(angle)));
+ float y = (float) (height / 2.0f + radius * (Math.sin(angle)));
+ return new Point(x, y);
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators = new ArrayList<>();
+ int[] delays = {0, 120, 240, 360, 480, 600, 720, 780, 840};
+ for (int i = 0; i < 8; i++) {
+ final int index = i;
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(1000);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setDelay(delays[i]);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloats[index] = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+
+ AnimatorValue alphaAnim = new AnimatorValue();
+ alphaAnim.setDuration(1000);
+ alphaAnim.setDelay(delays[i]);
+ alphaAnim.setLoopedCount(-1);
+ alphaAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ alphas[index] = (int) v;
+ postInvalidate();
+ }
+ });
+ alphaAnim.start();
+ animators.add(scaleAnim);
+ animators.add(alphaAnim);
+ }
+ return animators;
+ }
+
+ public static class Point {
+ public float x;
+ public float y;
+
+ public Point(float x, float y) {
+ this.x = x;
+ this.y = y;
+ }
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallTrianglePathIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallTrianglePathIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..a3d483d436c131f110c82023087e242a07bb0946
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallTrianglePathIndicator.java
@@ -0,0 +1,51 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallTrianglePathIndicator extends BaseIndicatorController {
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float radius=getWidth()/10.0f;
+ float x = getWidth()/ 2.0f;
+ float y=getHeight()/2.0f;
+
+ canvas.save();
+ canvas.translate(x - radius * 2 - radius, y+y/2);
+ canvas.drawCircle(0, 0, radius, paint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(x, y/2);
+ canvas.drawCircle(0, 0, radius, paint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(x + radius * 2 + radius, y+y/2);
+ canvas.drawCircle(0,0,radius, paint);
+ canvas.restore();
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setDuration(1500);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ getTarget().setRotation(v*180);
+ }
+ });
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallZigZagDeflectIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallZigZagDeflectIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..c2e23c673981f5061308329f0ca981cb5d1ed88c
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallZigZagDeflectIndicator.java
@@ -0,0 +1,50 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallZigZagDeflectIndicator extends BallZigZagIndicator {
+ private float scaleFloat=0.5f;
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float radius=getWidth()/10.0f;
+ float x = getWidth()/ 2.0f;
+ float y=getHeight()/2.0f;
+
+ canvas.save();
+ canvas.translate(x - radius * 2 - radius, y);
+ canvas.scale(scaleFloat, scaleFloat);
+ canvas.drawCircle(0, 0, radius, paint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(x + radius * 2 + radius, y);
+ canvas.scale(scaleFloat, scaleFloat);
+ canvas.drawCircle(0,0,radius, paint);
+ canvas.restore();
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setDuration(1500);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloat = v;
+ getTarget().setRotation(v*180);
+ }
+ });
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallZigZagIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallZigZagIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e8e054369b8397f98aeff78779fdf9dfc051c1d
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BallZigZagIndicator.java
@@ -0,0 +1,51 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BallZigZagIndicator extends BaseIndicatorController {
+ private float scaleFloat=0.5f;
+
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float radius=getWidth()/10.0f;
+ float x = getWidth()/ 2.0f;
+ float y=getHeight()/2.0f;
+
+ canvas.save();
+ canvas.translate(x - radius * 2 - radius, y);
+ canvas.scale(scaleFloat, scaleFloat);
+ canvas.drawCircle(0, 0, radius, paint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(x + radius * 2 + radius, y);
+ canvas.scale(scaleFloat, scaleFloat);
+ canvas.drawCircle(0,0,radius, paint);
+ canvas.restore();
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setDuration(1500);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloat = v;
+ getTarget().setRotation(v*180);
+ }
+ });
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BaseIndicatorController.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BaseIndicatorController.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e06b5f4e203b714d42502131afeae0e9a5198c5
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/BaseIndicatorController.java
@@ -0,0 +1,103 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.components.Component;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+
+import java.util.List;
+
+public abstract class BaseIndicatorController {
+
+ private Component mTarget;
+ private List mAnimators;
+
+ public void destroy(){
+ mTarget = null;
+ releaseAnimations();
+ mAnimators = null;
+ }
+
+ public void setTarget(Component target){
+ this.mTarget=target;
+ }
+
+ public Component getTarget(){
+ return mTarget;
+ }
+
+ public int getWidth(){
+ if(mTarget == null){
+ return 0;
+ }
+ return mTarget.getWidth();
+ }
+
+ public int getHeight(){
+ if(mTarget == null){
+ return 0;
+ }
+ return mTarget.getHeight();
+ }
+
+ public void postInvalidate(){
+ if(mTarget != null){
+ mTarget.invalidate();
+ }
+ }
+
+ public abstract void draw(Canvas canvas, Paint paint);
+ public abstract List createAnimation();
+
+ public void initAnimation(){
+ mAnimators=createAnimation();
+ }
+
+
+ private void releaseAnimations(){
+ if (mAnimators==null){
+ return;
+ }
+ int count=mAnimators.size();
+ for (int i = 0; i < count; i++) {
+ Animator animator = mAnimators.get(i);
+ animator.cancel();
+// animator.removeAllListeners();
+ }
+ mAnimators.clear();
+ mAnimators = null;
+ }
+
+ public void setAnimationStatus(AnimStatus animStatus){
+ if (mAnimators==null){
+ return;
+ }
+ int count=mAnimators.size();
+ for (int i = 0; i < count; i++) {
+ Animator animator=mAnimators.get(i);
+ boolean isRunning=animator.isRunning();
+ switch (animStatus){
+ case START:
+ if (!isRunning){
+ animator.start();
+ }
+ break;
+ case END:
+ if (isRunning){
+ animator.end();
+ }
+ break;
+ case CANCEL:
+ if (isRunning){
+ animator.cancel();
+ }
+ break;
+ }
+ }
+ }
+
+
+ public enum AnimStatus{
+ START,END,CANCEL
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/CubeTransitionIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/CubeTransitionIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a7110556266071cbd5005d153a471be2e169596
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/CubeTransitionIndicator.java
@@ -0,0 +1,68 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.RectFloat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CubeTransitionIndicator extends BaseIndicatorController {
+ private float scaleFloat=1;
+ private float degrees;
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ paint.setStrokeWidth(3);
+ paint.setStyle(Paint.Style.STROKE_STYLE);
+ float circleSpacing=12;
+ float x=getWidth()/3.0f;
+ float y=getHeight()/3.0f;
+
+ canvas.save();
+
+ canvas.translate(x, y);
+ canvas.scale(scaleFloat, scaleFloat);
+ canvas.rotate(degrees*360,0,0);
+ RectFloat rectF=new RectFloat(-x+circleSpacing,-y+circleSpacing,x-circleSpacing,y-circleSpacing);
+ canvas.drawRect(rectF,paint);
+
+ float x2=getWidth()/6.0f;
+ float y2=getHeight()/6.0f;
+ RectFloat rectF2=new RectFloat(-x2+circleSpacing,-y2+circleSpacing,x2-circleSpacing,y2-circleSpacing);
+ canvas.drawRect(rectF2,paint);
+ canvas.restore();
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(1000);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloat = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+
+ AnimatorValue rotateAnim = new AnimatorValue();
+ rotateAnim.setDuration(1000);
+ rotateAnim.setLoopedCount(-1);
+ rotateAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ degrees = v;
+ postInvalidate();
+ }
+ });
+ rotateAnim.start();
+ animators.add(scaleAnim);
+ animators.add(rotateAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineScaleIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineScaleIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c83402077939a1252fe9d7f5955efd9fc0c2117
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineScaleIndicator.java
@@ -0,0 +1,57 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.RectFloat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LineScaleIndicator extends BaseIndicatorController {
+
+ public static final float SCALE=1.0f;
+
+ float[] scaleYFloats=new float[]{SCALE,
+ SCALE,
+ SCALE,
+ SCALE,
+ SCALE,};
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float translateX=getWidth()/11.0f;
+ float translateY=getHeight()/2.0f;
+ for (int i = 0; i < 5; i++) {
+ canvas.save();
+ canvas.translate((2 + i * 2) * translateX - translateX / 2, translateY);
+ canvas.scale(SCALE, scaleYFloats[i]);
+ RectFloat rectF=new RectFloat(-translateX/2,-getHeight()/2.5f,translateX/2,getHeight()/2.5f);
+ canvas.drawRoundRect(rectF, 4, 4, paint);
+ canvas.restore();
+ }
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ long[] delays=new long[]{100,200,300,400,500};
+ for (int i = 0; i < 5; i++) {
+ final int index=i;
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(1000);
+ scaleAnim.setDelay(delays[i]);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleYFloats[index] = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ }
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineScalePartyIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineScalePartyIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..e5f2eb209ab5f01d78e617f2641c4c9decba626f
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineScalePartyIndicator.java
@@ -0,0 +1,58 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.RectFloat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LineScalePartyIndicator extends BaseIndicatorController {
+
+ public static final float SCALE=1.0f;
+
+ float[] scaleFloats=new float[]{SCALE,
+ SCALE,
+ SCALE,
+ SCALE,
+ SCALE,};
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float translateX=getWidth()/9.0f;
+ float translateY=getHeight()/2.0f;
+ for (int i = 0; i < 4; i++) {
+ canvas.save();
+ canvas.translate((2 + i * 2) * translateX - translateX / 2, translateY);
+ canvas.scale(scaleFloats[i], scaleFloats[i]);
+ RectFloat rectF=new RectFloat(-translateX/2,-getHeight()/2.5f,translateX/2,getHeight()/2.5f);
+ canvas.drawRoundRect(rectF,3.5f,3.5f,paint);
+ canvas.restore();
+ }
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ long[] durations=new long[]{1260, 430, 1010, 730};
+ long[] delays=new long[]{770, 290, 280, 740};
+ for (int i = 0; i < 4; i++) {
+ final int index=i;
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(durations[i]);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setDelay(delays[i]);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleFloats[index] = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ }
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineScalePulseOutIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineScalePulseOutIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..310916c0634f7ee576e1ef3efa447b6a8d934eea
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineScalePulseOutIndicator.java
@@ -0,0 +1,32 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LineScalePulseOutIndicator extends LineScaleIndicator {
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ long[] delays=new long[]{500,250,0,250,500};
+ for (int i = 0; i < 5; i++) {
+ final int index=i;
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(900);
+ scaleAnim.setDelay(delays[i]);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleYFloats[index] = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ }
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineScalePulseOutRapidIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineScalePulseOutRapidIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..aa8437cf1c24d963bf23be69ec20dca89615dd33
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineScalePulseOutRapidIndicator.java
@@ -0,0 +1,31 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LineScalePulseOutRapidIndicator extends LineScaleIndicator {
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ long[] delays=new long[]{400,200,0,200,400};
+ for (int i = 0; i < 5; i++) {
+ final int index=i;
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(1000);
+ scaleAnim.setDelay(delays[i]);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ scaleYFloats[index] = v;
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ }
+ return animators; }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineSpinFadeLoaderIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineSpinFadeLoaderIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..16d7f9b788560deff17c427d569f7758caaed6ae
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/LineSpinFadeLoaderIndicator.java
@@ -0,0 +1,23 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.RectFloat;
+
+public class LineSpinFadeLoaderIndicator extends BallSpinFadeLoaderIndicator {
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ float radius=getWidth()/10.0f;
+ for (int i = 0; i < 8; i++) {
+ canvas.save();
+ Point point=circleAt(getWidth(),getHeight(),getWidth()/2.5f-radius,i*(Math.PI/4));
+ canvas.translate(point.x, point.y);
+ canvas.scale(scaleFloats[i], scaleFloats[i]);
+ canvas.rotate(i*45,0,0);
+// paint.setAlpha(alphas[i]);
+ RectFloat rectF=new RectFloat(-radius,-radius/1.5f,1.5f*radius,radius/1.5f);
+ canvas.drawRoundRect(rectF,5,5,paint);
+ canvas.restore();
+ }
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/PacmanIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/PacmanIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..a4641462b303e77c7c1f1bb329581a4f424e4a22
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/PacmanIndicator.java
@@ -0,0 +1,119 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Arc;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.RectFloat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PacmanIndicator extends BaseIndicatorController {
+
+ private float translateX;
+
+ private int alpha;
+
+ private float degrees1,degrees2;
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ drawPacman(canvas,paint);
+ drawCircle(canvas,paint);
+ }
+
+ private void drawPacman(Canvas canvas,Paint paint){
+ float x=getWidth()/2.0f;
+ float y=getHeight()/2.0f;
+
+ canvas.save();
+
+ canvas.translate(x, y);
+ canvas.rotate(degrees1,0,0);
+ paint.setAlpha(255);
+ RectFloat rectF1=new RectFloat(-x/1.7f,-y/1.7f,x/1.7f,y/1.7f);
+ Arc mArc = new Arc();
+ mArc.setArc(0, 270, true);
+ canvas.drawArc(rectF1, mArc, paint);
+
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(x, y);
+ canvas.rotate(degrees2,0,0);
+ paint.setAlpha(255);
+ RectFloat rectF2=new RectFloat(-x/1.7f,-y/1.7f,x/1.7f,y/1.7f);
+ Arc arc = new Arc();
+ arc.setArc(90,270,true);
+ canvas.drawArc(rectF2,arc,paint);
+ canvas.restore();
+ }
+
+
+ private void drawCircle(Canvas canvas, Paint paint) {
+ float radius=getWidth()/11.0f;
+ paint.setAlpha(alpha);
+ canvas.drawCircle(translateX, getHeight() / 2.0f, radius, paint);
+ }
+
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ AnimatorValue translationAnim = new AnimatorValue();
+ translationAnim.setDuration(650);
+ translationAnim.setCurveType(Animator.CurveType.SMOOTH_STEP);
+ translationAnim.setLoopedCount(-1);
+ translationAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ translateX = v;
+ postInvalidate();
+ }
+ });
+ translationAnim.start();
+
+ AnimatorValue alphaAnim =new AnimatorValue();
+ alphaAnim.setDuration(650);
+ alphaAnim.setLoopedCount(-1);
+ alphaAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ alpha = (int) v;
+ postInvalidate();
+ }
+ });
+ alphaAnim.start();
+
+ AnimatorValue rotateAnim1 = new AnimatorValue();
+ rotateAnim1.setDuration(650);
+ rotateAnim1.setLoopedCount(-1);
+ rotateAnim1.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ degrees1 = v;
+ postInvalidate();
+ }
+ });
+ rotateAnim1.start();
+
+ AnimatorValue rotateAnim2 = new AnimatorValue();
+ rotateAnim2.setDuration(650);
+ rotateAnim2.setLoopedCount(-1);
+ rotateAnim2.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ degrees2 = v;
+ postInvalidate();
+ }
+ });
+ rotateAnim2.start();
+
+ animators.add(translationAnim);
+ animators.add(alphaAnim);
+ animators.add(rotateAnim1);
+ animators.add(rotateAnim2);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/SemiCircleSpinIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/SemiCircleSpinIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..a6741c907044f52e4d885254c38e5a31dc23843d
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/SemiCircleSpinIndicator.java
@@ -0,0 +1,39 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Arc;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.RectFloat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SemiCircleSpinIndicator extends BaseIndicatorController {
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ RectFloat rectF=new RectFloat(0,0,getWidth(),getHeight());
+ Arc mArc = new Arc();
+ mArc.setArc(-60,120,false);
+ canvas.drawArc(rectF,mArc,paint);
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setDuration(600);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ getTarget().setRotation(v*360);
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/SquareSpinIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/SquareSpinIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..c908014eef69876e569f369dce1f828a763eeeea
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/SquareSpinIndicator.java
@@ -0,0 +1,45 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.RectFloat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SquareSpinIndicator extends BaseIndicatorController {
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ canvas.drawRect(new RectFloat(getWidth()/5.0f,getHeight()/5.0f,getWidth()*4/5.0f,getHeight()*4/5.0f),paint);
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(2500);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ getTarget().setRotation(v*180);
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+// PropertyValuesHolder rotation5=PropertyValuesHolder.ofFloat("rotationX",0,180,180,0,0);
+// PropertyValuesHolder rotation6=PropertyValuesHolder.ofFloat("rotationY",0,0,180,180,0);
+//
+// ObjectAnimator animator=ObjectAnimator.ofPropertyValuesHolder(getTarget(), rotation6,rotation5);
+// animator.setInterpolator(new LinearInterpolator());
+// animator.setRepeatCount(-1);
+// animator.setDuration(2500);
+// animator.start();
+// animators.add(mAnimatorSet);
+
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/SysProgressIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/SysProgressIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6678b6f7f4063dabe6c064126c50579ca0da992
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/SysProgressIndicator.java
@@ -0,0 +1,61 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import com.lcodecore.tkrefreshlayout.utils.DeviceUtils;
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Arc;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.RectFloat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SysProgressIndicator extends BaseIndicatorController{
+ private float degrees;
+ private Arc mArc = new Arc();//弧度
+
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ paint.setStyle(Paint.Style.STROKE_STYLE);
+ paint.setStrokeWidth(DeviceUtils.dp2px(getTarget().getContext(),2));
+ float x = (getWidth()) / 3.0f;
+ float y=(getHeight()) / 3.0f;
+ canvas.translate(x, y);
+ canvas.rotate(degrees*360,0,0);
+ RectFloat rectF=new RectFloat(-x,-y+5,
+ x,y);
+ mArc.setArc( 0, 270, false);
+ canvas.drawArc(rectF,mArc,paint);
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setDuration(750);
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+
+ AnimatorValue rotateAnim = new AnimatorValue();
+ rotateAnim.setDuration(750);
+ rotateAnim.setLoopedCount(-1);
+ rotateAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ degrees = v;
+ postInvalidate();
+ }
+ });
+ rotateAnim.start();
+ animators.add(scaleAnim);
+ animators.add(rotateAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/TriangleSkewSpinIndicator.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/TriangleSkewSpinIndicator.java
new file mode 100644
index 0000000000000000000000000000000000000000..fdbd657c70f3b8f4b371d35dfabbb2caa28a42df
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/indicator/TriangleSkewSpinIndicator.java
@@ -0,0 +1,40 @@
+package com.lcodecore.tkrefreshlayout.processor.indicator;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.render.Path;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriangleSkewSpinIndicator extends BaseIndicatorController {
+ @Override
+ public void draw(Canvas canvas, Paint paint) {
+ Path path=new Path();
+ path.moveTo(getWidth()/5.0f,getHeight()*4/5.0f);
+ path.lineTo(getWidth()*4/5.0f, getHeight()*4/5.0f);
+ path.lineTo(getWidth()/2.0f,getHeight()/5.0f);
+ path.close();
+ canvas.drawPath(path, paint);
+ }
+
+ @Override
+ public List createAnimation() {
+ List animators=new ArrayList<>();
+ AnimatorValue scaleAnim = new AnimatorValue();
+ scaleAnim.setLoopedCount(-1);
+ scaleAnim.setDuration(2000);
+ scaleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ getTarget().setRotation(v*360);
+ postInvalidate();
+ }
+ });
+ scaleAnim.start();
+ animators.add(scaleAnim);
+ return animators;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/loading/LoadingBuilder.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/loading/LoadingBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..71b8d9c4b9e4f03d6f1b5dc5500ce1b3228dab67
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/loading/LoadingBuilder.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * 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 an copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.tkrefreshlayout.processor.loading;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.components.element.Element;
+import ohos.agp.render.Arc;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+import ohos.agp.utils.RectFloat;
+import ohos.agp.window.service.Display;
+import ohos.agp.window.service.DisplayAttributes;
+import ohos.agp.window.service.DisplayManager;
+import ohos.app.Context;
+
+import java.math.BigDecimal;
+import java.util.Optional;
+
+/**
+ * 加载Drawable
+ *
+ * @author czf
+ * @since 2021-05-12
+ */
+public class LoadingBuilder implements AnimatorValue.ValueUpdateListener, Animator.LoopedListener,
+ Animator.StateChangedListener {
+ /**
+ * 外部可以修改,但是不建议
+ */
+ public static final float DEFAULT_SIZE = 55.0f;
+ protected static final long ANIMATION_START_DELAY = 333L;
+ protected static final long ANIMATION_DURATION = 800L;
+ protected static final int ANGLE = 360;
+ protected static final float HALF = 0.5f;
+ protected static final float INR = 0.6f;
+ protected static final float INITPAINT = 0.4f;
+ protected static final int TWELVE = 12;
+ private static final int OUTER_CIRCLE_ANGLE = 320;
+ private float mAllSize;
+ private float mViewWidth;
+ private float mViewHeight;
+ private Element.OnChangeListener mCallback;
+ private AnimatorValue mFloatValueAnimator;
+ private int mCurrAnimatorState = 0;
+ private Paint mStrokePaint;
+ private RectFloat mOuterCircleRectF;
+ private float mDefaultSize = DEFAULT_SIZE;
+
+ // 旋转开始角度
+ private int mStartRotateAngle;
+
+ // 旋转角度
+ private int mRotateAngle;
+ private Arc mArc;
+ private int colorid = 1;
+ private int setcolor = 0;
+ private float updatecolor = 0;
+ void init(Context context) {
+ mAllSize = dip2px(context, new BigDecimal(Float.toString(mDefaultSize)).
+ multiply(new BigDecimal(Float.toString(HALF))).
+ subtract(new BigDecimal(Float.toString(TWELVE))).floatValue());
+ mViewWidth = dip2px(context, mDefaultSize);
+ mViewHeight = dip2px(context, mDefaultSize);
+ initAnimators();
+ }
+
+ private void initAnimators() {
+ mFloatValueAnimator = new AnimatorValue();
+ mFloatValueAnimator.setLoopedCount(AnimatorProperty.INFINITE);
+ mFloatValueAnimator.setDuration(getAnimationDuration());
+ mFloatValueAnimator.setDelay(getAnimationStartDelay());
+ mFloatValueAnimator.setCurveType(Animator.CurveType.LINEAR);
+ }
+
+ void setCallback(Element.OnChangeListener callback) {
+ this.mCallback = callback;
+ }
+
+ /**
+ * 设置mDefaultSizee大小
+ *
+ * @param defaultSize 宽
+ */
+ public void setDefaultSize(int defaultSize) {
+ this.mDefaultSize = defaultSize;
+ }
+
+ /**
+ * 初始化Params
+ *
+ * @param color 颜色
+ */
+ protected void initParams(Color color,int colorId) {
+ setcolor = colorId;
+ mArc = new Arc();
+
+ // 最大尺寸
+ float outR = getAllSize();
+
+ // 小圆尺寸
+ float inR = outR * INR;
+
+ // 初始化画笔
+ if(colorId == 1) {
+ initPaint(inR * INITPAINT, new Color(0xffB5B5B5));
+ } else {
+ initPaint(inR * INITPAINT, color);
+ }
+
+ // 旋转角度
+ mStartRotateAngle = 0;
+
+ // 圆范围
+ mOuterCircleRectF = new RectFloat();
+ mOuterCircleRectF.fuse(new BigDecimal(Float.toString(getViewCenterX())).
+ subtract(new BigDecimal(Float.toString(outR))).floatValue(),
+ new BigDecimal(Float.toString(getViewCenterY())).
+ subtract(new BigDecimal(Float.toString(outR))).floatValue(),
+ new BigDecimal(Float.toString(getViewCenterX())).
+ add(new BigDecimal(Float.toString(outR))).floatValue(),
+ new BigDecimal(Float.toString(getViewCenterY())).
+ add(new BigDecimal(Float.toString(outR))).floatValue());
+ }
+
+ /**
+ * 初始化画笔
+ *
+ * @param lineWidth 宽度
+ * @param color 颜色
+ */
+ private void initPaint(float lineWidth, Color color) {
+ mStrokePaint = new Paint();
+ mStrokePaint.setStyle(Paint.Style.STROKE_STYLE);
+ mStrokePaint.setStrokeWidth(lineWidth);
+ mStrokePaint.setColor(color);
+ mStrokePaint.setDither(true);
+ mStrokePaint.setFilterBitmap(true);
+ mStrokePaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
+ mStrokePaint.setStrokeJoin(Paint.Join.ROUND_JOIN);
+ }
+
+ /**
+ * onDraw方法
+ *
+ * @param canvas 画布
+ */
+ protected void onDraw(Canvas canvas) {
+ canvas.save();
+ if(setcolor == 1) {
+ if (updatecolor > 0.8) {
+ if (colorid == 1) {
+ mStrokePaint.setColor(new Color(Color.getIntColor("#005AB5")));
+ } else if (colorid == 2) {
+ mStrokePaint.setColor(new Color(Color.getIntColor("#EA0000")));
+ } else if (colorid == 3) {
+ mStrokePaint.setColor(new Color(Color.getIntColor("#FFD306")));
+ } else if (colorid == 4) {
+ mStrokePaint.setColor(new Color(Color.getIntColor("#73BF00")));
+ }
+ }
+ }
+ /*
+ 外圆
+ */
+ mArc.setArc(mStartRotateAngle, mRotateAngle, false);
+ canvas.drawArc(mOuterCircleRectF, mArc, mStrokePaint);
+ canvas.restore();
+ if(setcolor == 1) {
+ if (updatecolor > 0.8) {
+ if (colorid <= 4) {
+ colorid++;
+ } else {
+ colorid = 1;
+ }
+ }
+ }
+ }
+
+
+
+ /**
+ * 设置computeUpdateValue
+ *
+ * @param animatedValue 动画值
+ */
+ protected void computeUpdateValue(float animatedValue) {
+ mStartRotateAngle = (int) (ANGLE * animatedValue);
+ switch (mCurrAnimatorState) {
+ case 0:
+ mRotateAngle = (int) (OUTER_CIRCLE_ANGLE * animatedValue);
+ break;
+ case 1:
+ mRotateAngle = OUTER_CIRCLE_ANGLE - (int) (OUTER_CIRCLE_ANGLE * animatedValue);
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public void onRepeat(Animator animator) {
+ // 还原到第一阶段
+ mFloatValueAnimator.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
+ mCurrAnimatorState = mCurrAnimatorState == 0 ? 1 : 0;
+ }
+
+ /**
+ * 设置computeUpdateValue
+ */
+ public void setRepeat() {
+ // 还原到第一阶段
+ mFloatValueAnimator.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
+ mCurrAnimatorState = mCurrAnimatorState == 0 ? 1 : 0;
+ }
+
+ void draw(Canvas canvas) {
+ onDraw(canvas);
+ }
+
+ void start() {
+ if (mFloatValueAnimator.isRunning()) {
+ return;
+ }
+ mFloatValueAnimator.setValueUpdateListener(this);
+ mFloatValueAnimator.setStateChangedListener(this);
+ mFloatValueAnimator.setLoopedListener(this);
+ mFloatValueAnimator.setLoopedCount(AnimatorProperty.INFINITE);
+ mFloatValueAnimator.setDuration(getAnimationDuration());
+ mFloatValueAnimator.start();
+ }
+
+ void stop() {
+ mFloatValueAnimator.setValueUpdateListener(null);
+ mFloatValueAnimator.setLoopedListener(null);
+ mFloatValueAnimator.setLoopedCount(0);
+ mFloatValueAnimator.setDuration(0);
+ mFloatValueAnimator.end();
+ }
+
+ @Override
+ public void onUpdate(AnimatorValue animation, float v) {
+ updatecolor = v;
+
+ computeUpdateValue(v);
+ invalidateSelf();
+ }
+
+ private void invalidateSelf() {
+ if (mCallback != null) {
+ mCallback.onChange(null);
+ }
+ }
+
+ @Override
+ public void onStart(Animator animator) {
+ }
+
+ @Override
+ public void onEnd(Animator animator) {
+ }
+
+ @Override
+ public void onCancel(Animator animator) {
+ }
+
+ @Override
+ public void onResume(Animator animator) {
+ }
+
+ @Override
+ public void onStop(Animator animator) {
+ }
+
+ @Override
+ public void onPause(Animator animator) {
+ }
+
+ protected long getAnimationStartDelay() {
+ return ANIMATION_START_DELAY;
+ }
+
+ /**
+ * 获取动画持续时间
+ *
+ * @return float
+ */
+ protected long getAnimationDuration() {
+ double mDurationTimePercent = 1.0;
+ return ceil(ANIMATION_DURATION * mDurationTimePercent);
+ }
+
+ protected float getIntrinsicHeight() {
+ return mViewHeight;
+ }
+
+ protected float getIntrinsicWidth() {
+ return mViewWidth;
+ }
+
+ protected final float getViewCenterX() {
+ return getIntrinsicWidth() * HALF;
+ }
+
+ protected final float getViewCenterY() {
+ return getIntrinsicHeight() * HALF;
+ }
+
+ protected final float getAllSize() {
+ return mAllSize;
+ }
+
+ /**
+ * dp转px
+ *
+ * @param context 上下文
+ * @param dpValue dpValue
+ * @return float
+ */
+ public static float dip2px(Context context, float dpValue) {
+ DisplayAttributes displayAttributes = getScreenPiex(context);
+ return dpValue * displayAttributes.scalDensity;
+ }
+
+ /**
+ * 获取屏幕图片
+ *
+ * @param context 上下文
+ * @return displayAttributes
+ */
+ public static DisplayAttributes getScreenPiex(Context context) {
+ Optional display = DisplayManager.getInstance().getDefaultDisplay(context);
+ return display.get().getAttributes();
+ }
+
+ /**
+ * 路径
+ *
+ * @param value value
+ * @return Math.ceil(value)
+ */
+ protected static long ceil(double value) {
+ return (long) Math.ceil(value);
+ }
+}
+
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/loading/LoadingDrawable.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/loading/LoadingDrawable.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7c6f87c1c3573bd59d0e66c6abc16df3d0b5abb
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/loading/LoadingDrawable.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * 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 an copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.tkrefreshlayout.processor.loading;
+
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+import ohos.agp.render.Canvas;
+import ohos.app.Context;
+
+/**
+ * 加载Drawable
+ *
+ * @author czf
+ * @since 2021-05-12
+ */
+public class LoadingDrawable extends Image implements Component.DrawTask {
+ private LoadingBuilder mLoadingBuilder;
+
+ /**
+ * 构造方法
+ *
+ * @param context 上下文
+ */
+ public LoadingDrawable(Context context) {
+ super(context, null);
+ }
+
+ /**
+ * 构造方法
+ *
+ * @param loadingBuilder 加载Builder
+ */
+ public void setmLoadingBuilder(LoadingBuilder loadingBuilder) {
+ this.mLoadingBuilder = loadingBuilder;
+ }
+
+ /**
+ * 开始
+ */
+ public void start() {
+ this.mLoadingBuilder.start();
+ }
+
+ /**
+ * 结束
+ */
+ public void stop() {
+ this.mLoadingBuilder.stop();
+ }
+
+ /**
+ * 结束
+ */
+ public void setRepeat() {
+ this.mLoadingBuilder.setRepeat();
+ }
+
+ @Override
+ public int getWidth() {
+ return (int) this.mLoadingBuilder.getIntrinsicWidth();
+ }
+
+ @Override
+ public int getHeight() {
+ return (int) this.mLoadingBuilder.getIntrinsicHeight();
+ }
+
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ component.setComponentSize(getWidth(), getHeight());
+ this.mLoadingBuilder.draw(canvas);
+ }
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/loading/LoadingView.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/loading/LoadingView.java
new file mode 100644
index 0000000000000000000000000000000000000000..5326cba51b94ed92d4c72d411fb13be2cda87b6c
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/loading/LoadingView.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * 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 an copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.tkrefreshlayout.processor.loading;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+import ohos.agp.components.element.Element;
+import ohos.agp.render.Canvas;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
+
+/**
+ * 加载view
+ *
+ * @author czf
+ * @since 2021-05-12
+ */
+public class LoadingView extends Image implements Component.BindStateChangedListener,
+ Element.OnChangeListener, Component.DrawTask {
+ protected LoadingBuilder mLoadingBuilder;
+ private LoadingDrawable mLoadingDrawable;
+ private int mPaintcolor;
+ private int mSize;
+
+ /**
+ * 构造方法
+ *
+ * @param context 上下文
+ */
+ public LoadingView(Context context) {
+ this(context, null);
+ this.mContext = context;
+ }
+
+ /**
+ * 构造方法
+ *
+ * @param context 上下文
+ * @param attrs 线下像素
+ */
+ public LoadingView(Context context, AttrSet attrs) {
+ this(context, attrs, "");
+ this.mContext = context;
+ }
+
+ /**
+ * 构造方法
+ *
+ * @param context 上下文
+ * @param attrs 线下像素
+ * @param defStyleAttr 定义样式属性
+ */
+ public LoadingView(Context context, AttrSet attrs, String defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ /**
+ * 设置画笔颜色
+ *
+ * @param paintcolor 颜色
+ */
+ public void setPaintcolor(int paintcolor) {
+ this.mPaintcolor = paintcolor;
+ initLoadingDrawable();
+ }
+
+ /**
+ * 设置宽高
+ *
+ * @param size 宽
+ */
+ public void setSize(int size) {
+ this.mSize = size;
+ initLoadingDrawable();
+ }
+
+ private void initLoadingDrawable() {
+ mLoadingBuilder = new LoadingBuilder();
+ mLoadingDrawable = new LoadingDrawable(getContext());
+ mLoadingDrawable.setmLoadingBuilder(mLoadingBuilder);
+ initParams(getContext(), new Color(mPaintcolor), mSize,mPaintcolor);
+ this.addDrawTask(mLoadingDrawable);
+ mLoadingBuilder.setCallback(this);
+ }
+
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ this.mLoadingBuilder.draw(canvas);
+ }
+
+ @Override
+ public void setVisibility(int visibility) {
+ if (getVisibility() != visibility) {
+ super.setVisibility(visibility);
+ if (visibility == HIDE || visibility == INVISIBLE) {
+ startAnimation();
+ } else {
+ stopAnimation();
+ }
+ }
+ }
+
+ /**
+ * 开始动画
+ */
+ public void startAnimation() {
+ if (mLoadingDrawable != null) {
+ mLoadingDrawable.start();
+ }
+ }
+
+ /**
+ * 结束动画
+ */
+ public void stopAnimation() {
+ if (mLoadingDrawable != null) {
+ mLoadingDrawable.stop();
+ }
+ }
+
+ /**
+ * 结束动画
+ */
+ public void repeatAnimationn() {
+ if (mLoadingDrawable != null) {
+ mLoadingDrawable.setRepeat();
+ }
+ }
+
+ @Override
+ public void onComponentBoundToWindow(Component component) {
+ startAnimation();
+ }
+
+ void initParams(Context context, Color color, int size,int colorId) {
+ if (mLoadingBuilder != null) {
+ mLoadingBuilder.setDefaultSize(size);
+ mLoadingBuilder.init(context);
+ mLoadingBuilder.initParams(color,colorId);
+ }
+ }
+
+ @Override
+ public void onComponentUnboundFromWindow(Component component) {
+ stopAnimation();
+ }
+
+ @Override
+ public void onChange(Element element) {
+ this.addDrawTask(mLoadingDrawable);
+ }
+}
+
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/AnimatorValueUtil.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/AnimatorValueUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..68da4642fe70ddde633b66f41e9f90f06a228c71
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/AnimatorValueUtil.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.tkrefreshlayout.utils;
+
+/**
+ * ex.
+ * AnimatorValueUtil animatorValueUtil = new AnimatorValueUtil();
+ * animatorValueUtil.ofFloat(0.1f,-3f,2f)
+ * public void onUpdate(AnimatorValue animatorValue, float v) {
+ * float currentV = animatorValueUtil.getValue(v);
+ * }
+ *
+ * @since 2021-07-19
+ */
+public class AnimatorValueUtil {
+ private static final String TAG = "AnimatorValueUtil";
+ private static final int RATE_SIZE = 2;
+ private static final int NEGATIVE = -1;
+ private float[] values;
+ private float[][] rate;
+
+ /**
+ * 如传一个参数,则getValue 返回值与传入的 V 值一致
+ * 如传入连续两个相同参数,则会出现除0异常
+ * 传参试例: 0.8f,-1.2f,3.5f,0,5
+ *
+ * @param tempValues 说明
+ */
+ public void ofFloat(float... tempValues) {
+ this.values = tempValues;
+
+ rate = new float[this.values.length - 1][RATE_SIZE];
+
+ float sum = 0;
+
+ for (int ii = 1; ii < this.values.length; ii++) {
+ sum += Math.abs(this.values[ii] - this.values[ii - 1]);
+ }
+
+ // 计算每个变化值的占比和达到该变化值系数
+ for (int ii = 0; ii < rate.length; ii++) {
+ float tempRate = Math.abs((this.values[ii + 1] - this.values[ii]) / sum);
+ rate[ii][0] = tempRate + (ii == 0 ? 0 : rate[ii - 1][0]);
+ float tempDuration = this.values[ii + 1] - this.values[ii];
+ rate[ii][1] = (this.values[ii] > this.values[ii + 1] ? NEGATIVE : 1) * Math.abs(tempDuration / tempRate);
+ }
+ }
+
+ /**
+ * 根据 属性动画中value的值,计算当前值
+ *
+ * @param value 属性动画中的value
+ * @return 通过计算后的值
+ */
+ public float getValue(float value) {
+ for (int ii = 0; ii < rate.length; ii++) {
+ // 如果是进入当前变化值占比,则按当前系数进行计算实际值(bounce回弹效果最后v会大于1)
+ if (value <= rate[ii][0] || value > 1) {
+ return values[ii] + (ii == 0 ? value : value - rate[ii - 1][0]) * rate[ii][1];
+ }
+ }
+ return value;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/AttrUtils.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/AttrUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ecb7ac3bb5fa2e95db0868e7b74983ba342e80b
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/AttrUtils.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.tkrefreshlayout.utils;
+
+import ohos.agp.components.AttrSet;
+
+/**
+ * AttrUtils
+ *
+ * @since 2021-07-19
+ */
+public class AttrUtils {
+ private AttrUtils() {
+ }
+
+ /**
+ * get the int value from AttrSet
+ *
+ * @param attrs the attrSet
+ * @param name the attrName
+ * @param defaultValue the defaultValue
+ * @return int value
+ */
+ public static int getIntFromAttr(AttrSet attrs, String name, int defaultValue) {
+ int value = defaultValue;
+ try {
+ if (attrs.getAttr(name).isPresent() && attrs.getAttr(name).get() != null) {
+ value = attrs.getAttr(name).get().getIntegerValue();
+ }
+ } catch (Exception e) {
+ return value;
+ }
+ return value;
+ }
+
+ /**
+ * get the float value from AttrSet
+ *
+ * @param attrs the attrSet
+ * @param name the attrName
+ * @param defaultValue the defaultValue
+ * @return float value
+ */
+ public static float getFloatFromAttr(AttrSet attrs, String name, float defaultValue) {
+ float value = defaultValue;
+ try {
+ if (attrs.getAttr(name).isPresent() && attrs.getAttr(name).get() != null) {
+ value = attrs.getAttr(name).get().getFloatValue();
+ }
+ } catch (Exception e) {
+ return value;
+ }
+ return value;
+ }
+
+ /**
+ * get the color value from AttrSet
+ *
+ * @param attrs the attrSet
+ * @param name the attrName
+ * @param defaultValue the defaultValue
+ * @return int colorValue
+ */
+ public static int getColorFromAttr(AttrSet attrs, String name, int defaultValue) {
+ int value = defaultValue;
+ try {
+ if (attrs.getAttr(name).isPresent() && attrs.getAttr(name).get() != null) {
+ value = attrs.getAttr(name).get().getColorValue().getValue();
+ }
+ } catch (Exception e) {
+ return value;
+ }
+ return value;
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/Constant.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/Constant.java
new file mode 100644
index 0000000000000000000000000000000000000000..57575c353d6e22593ec32d03d76d5bc0c3f657a7
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/Constant.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.tkrefreshlayout.utils;
+
+/**
+ * 常量工具类
+ *
+ * @since 2021-07-19
+ */
+public final class Constant {
+ /**
+ * numner 0.5f
+ */
+ public static final float ZOREFIVEF = 0.5f;
+
+ private Constant() {
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/DensityUtil.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/DensityUtil.java
index e75f6a8cd2adb30621ada19818698a0e78507fea..fcaeb8c6cc3ad9ea32fec82cd42811691c0a1b02 100755
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/DensityUtil.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/DensityUtil.java
@@ -1,6 +1,7 @@
package com.lcodecore.tkrefreshlayout.utils;
-import android.content.Context;
+
+import ohos.app.Context;
public class DensityUtil {
@@ -8,7 +9,7 @@ public class DensityUtil {
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dp2px(Context context, float dpValue) {
- final float scale = context.getResources().getDisplayMetrics().density;
+ final float scale = 8;
return (int) (dpValue * scale + 0.5f);
}
@@ -16,7 +17,7 @@ public class DensityUtil {
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public static int px2dp(Context context, float pxValue) {
- final float scale = context.getResources().getDisplayMetrics().density;
+ final float scale = 8;
return (int) (pxValue / scale + 0.5f);
}
}
\ No newline at end of file
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/DeviceUtils.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/DeviceUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..22ae2173a2ba99fc3e241355b5d94991f6c06da9
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/DeviceUtils.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.tkrefreshlayout.utils;
+
+import com.lcodecore.tkrefreshlayout.ResourceTable;
+import ohos.agp.components.Component;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.Text;
+import ohos.agp.window.dialog.ToastDialog;
+import ohos.app.Context;
+
+/**
+ * DeviceUtils
+ *
+ * @since 2021-07-19
+ */
+public class DeviceUtils {
+ private static final float NORMAL_PIXEL_DENSITY = 160f;
+
+ private DeviceUtils() {
+ }
+
+ /**
+ * dp2px
+ *
+ * @param context context
+ * @param dp dp
+ * @return dp2px
+ */
+ public static int dp2px(Context context, float dp) {
+ float scale = context.getResourceManager().getDeviceCapability().screenDensity;
+ return (int) (dp * scale / NORMAL_PIXEL_DENSITY + Constant.ZOREFIVEF);
+ }
+
+ /**
+ * Toast弹框
+ *
+ * @param context context
+ * @param content content
+ */
+ public static void showToast(Context context, String content) {
+ Component toastLayout = LayoutScatter.getInstance(context)
+ .parse(ResourceTable.Layout_layout_toast, null, false);
+ Text toastText = (Text) toastLayout.findComponentById(ResourceTable.Id_text_msg_toast);
+ toastText.setText(content);
+ new ToastDialog(context)
+ .setComponent(toastLayout)
+ .setTransparent(true)
+ .show();
+ }
+}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/LogUtil.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/LogUtil.java
index d6208f5103d1a899457b77ce9c73778b923e488d..52335ea9010cd8c6744d782ec201ac73de58c0a5 100644
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/LogUtil.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/LogUtil.java
@@ -1,16 +1,18 @@
package com.lcodecore.tkrefreshlayout.utils;
-import android.util.Log;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
/**
* Created by lcodecore on 2017/4/1.
*/
public class LogUtil {
+ private static final HiLogLabel LABEL_LOG = new HiLogLabel(10043, 0xD000f00, "MainAbility");
private static final boolean DEBUG = false;
public static void i(String msg) {
if (!DEBUG) return;
- Log.i("TwinklingRefreshLayout", msg);
+ HiLog.info(LABEL_LOG,"TwinklingRefreshLayout" + msg);
}
}
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/RectF.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/RectF.java
new file mode 100644
index 0000000000000000000000000000000000000000..7179d985f5a19508617106bf2fed20dbeb562ded
--- /dev/null
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/RectF.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.lcodecore.tkrefreshlayout.utils;
+
+import ohos.agp.utils.RectFloat;
+
+/**
+ * 文RectF
+ *
+ * @since 2021-07-19
+ */
+public class RectF extends RectFloat {
+ /**
+ * 构造函数
+ */
+ public RectF() {
+ super();
+ }
+
+ /**
+ * 构造函数
+ *
+ * @param left left
+ * @param top top
+ * @param right right
+ * @param bottom bottom
+ */
+ public RectF(float left, float top, float right, float bottom) {
+ super(left, top, right, bottom);
+ }
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/ScrollingUtil.java b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/ScrollingUtil.java
index d782b1a2ebecf8106502b63fefddbdf0a90f6eb5..b7a0cbd18a6f08de4fb70ecfd094a41fc4e6ef87 100644
--- a/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/ScrollingUtil.java
+++ b/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/ScrollingUtil.java
@@ -16,23 +16,21 @@
package com.lcodecore.tkrefreshlayout.utils;
-import android.content.Context;
-import android.graphics.Rect;
-import android.os.Build;
-import android.support.v4.view.ViewCompat;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.StaggeredGridLayoutManager;
-import android.util.DisplayMetrics;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.webkit.WebView;
-import android.widget.AbsListView;
-import android.widget.ScrollView;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.ListContainer;
+import ohos.agp.components.PageSlider;
+import ohos.agp.components.ScrollView;
+import ohos.agp.components.webengine.WebView;
+import ohos.agp.window.service.Display;
+import ohos.agp.window.service.DisplayAttributes;
+import ohos.agp.window.service.DisplayManager;
+import ohos.app.Context;
+import ohos.media.image.common.Rect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.util.Optional;
public class ScrollingUtil {
@@ -43,115 +41,87 @@ public class ScrollingUtil {
* 用来判断是否可以下拉
* 手指在屏幕上该方法才有效
*/
- public static boolean canChildScrollUp(View mChildView) {
+ public static boolean canChildScrollUp(Component mChildView) {
if (mChildView == null) {
return false;
}
- if (Build.VERSION.SDK_INT < 14) {
- if (mChildView instanceof AbsListView) {
- final AbsListView absListView = (AbsListView) mChildView;
- return absListView.getChildCount() > 0
- && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
- .getTop() < absListView.getPaddingTop());
- } else {
- return ViewCompat.canScrollVertically(mChildView, -1) || mChildView.getScrollY() > 0;
- }
- } else {
- return ViewCompat.canScrollVertically(mChildView, -1);
+ if (mChildView instanceof ListContainer) {
+ final ListContainer absListView = (ListContainer) mChildView;
+ return absListView.getChildCount() > 0
+ && (absListView.getFirstVisibleItemPosition() > 0 || absListView.getComponentAt(0)
+ .getTop() < absListView.getPaddingTop());
}
+ return true;
}
/**
* Whether it is possible for the child view of this layout to scroll down. Override this if the child view is a custom view.
* 判断是否可以上拉
*/
- public static boolean canChildScrollDown(View mChildView) {
- if (Build.VERSION.SDK_INT < 14) {
- if (mChildView instanceof AbsListView) {
- final AbsListView absListView = (AbsListView) mChildView;
- return absListView.getChildCount() > 0
- && (absListView.getLastVisiblePosition() < absListView.getChildCount() - 1
- || absListView.getChildAt(absListView.getChildCount() - 1).getBottom() > absListView.getPaddingBottom());
- } else {
- return ViewCompat.canScrollVertically(mChildView, 1) || mChildView.getScrollY() < 0;
- }
+ public static boolean canChildScrollDown(Component mChildView) {
+ if (mChildView instanceof ListContainer) {
+ final ListContainer absListView = (ListContainer) mChildView;
+ return absListView.getChildCount() > 0
+ && (absListView.getFirstVisibleItemPosition() < absListView.getChildCount() - 1
+ || absListView.getComponentAt(absListView.getChildCount() - 1).getBottom() > absListView.getPaddingBottom());
} else {
- return ViewCompat.canScrollVertically(mChildView, 1);
}
+ return true;
}
- public static boolean isScrollViewOrWebViewToTop(View view) {
- return view != null && view.getScrollY() == 0;
+ public static boolean isScrollViewOrWebViewToTop(Component view) {
+ return view != null && view.getScrollValue(0) == 0;
}
- public static boolean isViewToTop(View view, int mTouchSlop) {
- if (view instanceof AbsListView) return isAbsListViewToTop((AbsListView) view);
- if (view instanceof RecyclerView) return isRecyclerViewToTop((RecyclerView) view);
- return (view != null && Math.abs(view.getScrollY()) <= 2 * mTouchSlop);
+ public static boolean isViewToTop(Component view, int mTouchSlop) {
+ if (view instanceof ListContainer) return isAbsListViewToTop((ListContainer) view);
+ if (view instanceof ListContainer) return isRecyclerViewToTop((ListContainer) view);
+ return (view != null && Math.abs(view.getScrollValue(0)) <= 2 * mTouchSlop);
}
- public static boolean isViewToBottom(View view, int mTouchSlop) {
- if (view instanceof AbsListView) return isAbsListViewToBottom((AbsListView) view);
- if (view instanceof RecyclerView) return isRecyclerViewToBottom((RecyclerView) view);
+ public static boolean isViewToBottom(Component view, int mTouchSlop) {
+ if (view instanceof ListContainer) return isAbsListViewToBottom((ListContainer) view);
+ if (view instanceof ListContainer) return isRecyclerViewToBottom((ListContainer) view);
if (view instanceof WebView) return isWebViewToBottom((WebView) view, mTouchSlop);
- if (view instanceof ViewGroup) return isViewGroupToBottom((ViewGroup) view);
+ if (view instanceof PageSlider) return isViewGroupToBottom((PageSlider) view);
return false;
}
- public static boolean isAbsListViewToTop(AbsListView absListView) {
+ public static boolean isAbsListViewToTop(ListContainer absListView) {
if (absListView != null) {
int firstChildTop = 0;
if (absListView.getChildCount() > 0) {
// 如果AdapterView的子控件数量不为0,获取第一个子控件的top
- firstChildTop = absListView.getChildAt(0).getTop() - absListView.getPaddingTop();
+ firstChildTop = absListView.getComponentAt(0).getTop() - absListView.getPaddingTop();
}
- if (absListView.getFirstVisiblePosition() == 0 && firstChildTop == 0) {
+ if (absListView.getFirstVisibleItemPosition() == 0 && firstChildTop == 0) {
return true;
}
}
return false;
}
- public static boolean isRecyclerViewToTop(RecyclerView recyclerView) {
+ public static boolean isRecyclerViewToTop(ListContainer recyclerView) {
if (recyclerView != null) {
- RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
+ ComponentContainer.LayoutConfig manager = recyclerView.getLayoutConfig();
if (manager == null) {
return true;
}
- if (manager.getItemCount() == 0) {
- return true;
- }
int firstChildTop = 0;
if (recyclerView.getChildCount() > 0) {
// 处理item高度超过一屏幕时的情况
- View firstVisibleChild = recyclerView.getChildAt(0);
- if (firstVisibleChild != null && firstVisibleChild.getMeasuredHeight() >= recyclerView.getMeasuredHeight()) {
- if (android.os.Build.VERSION.SDK_INT < 14) {
- return !(ViewCompat.canScrollVertically(recyclerView, -1) || recyclerView.getScrollY() > 0);
- } else {
- return !ViewCompat.canScrollVertically(recyclerView, -1);
- }
+ Component firstVisibleChild = recyclerView.getComponentAt(0);
+ if (firstVisibleChild != null && firstVisibleChild.getEstimatedHeight() >= recyclerView.getEstimatedHeight()) {
}
// 如果RecyclerView的子控件数量不为0,获取第一个子控件的top
// 解决item的topMargin不为0时不能触发下拉刷新
- View firstChild = recyclerView.getChildAt(0);
- RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) firstChild.getLayoutParams();
- firstChildTop = firstChild.getTop() - layoutParams.topMargin - getRecyclerViewItemTopInset(layoutParams) - recyclerView.getPaddingTop();
+ Component firstChild = recyclerView.getComponentAt(0);
+ ComponentContainer.LayoutConfig layoutParams = (ListContainer.LayoutConfig) firstChild.getLayoutConfig();
}
- if (manager instanceof LinearLayoutManager) {
- LinearLayoutManager layoutManager = (LinearLayoutManager) manager;
- if (layoutManager.findFirstCompletelyVisibleItemPosition() < 1 && firstChildTop == 0) {
- return true;
- }
- } else if (manager instanceof StaggeredGridLayoutManager) {
- StaggeredGridLayoutManager layoutManager = (StaggeredGridLayoutManager) manager;
- int[] out = layoutManager.findFirstCompletelyVisibleItemPositions(null);
- if (out[0] < 1 && firstChildTop == 0) {
- return true;
- }
+ if (manager instanceof ComponentContainer.LayoutConfig) {
}
}
return false;
@@ -163,13 +133,14 @@ public class ScrollingUtil {
* @param layoutParams
* @return
*/
- private static int getRecyclerViewItemTopInset(RecyclerView.LayoutParams layoutParams) {
+ private static int getRecyclerViewItemTopInset(ComponentContainer.LayoutConfig layoutParams) {
try {
- Field field = RecyclerView.LayoutParams.class.getDeclaredField("mDecorInsets");
+ Field field = ListContainer.LayoutConfig.class.getDeclaredField("mDecorInsets");
field.setAccessible(true);
// 开发者自定义的滚动监听器
Rect decorInsets = (Rect) field.get(layoutParams);
- return decorInsets.top;
+// return decorInsets.top;
+ return decorInsets.width;
} catch (Exception e) {
e.printStackTrace();
}
@@ -178,18 +149,19 @@ public class ScrollingUtil {
public static boolean isWebViewToBottom(WebView webview, int mTouchSlop) {
- return webview != null && ((webview.getContentHeight() * webview.getScale() - (webview.getHeight() + webview.getScrollY())) <= 2 * mTouchSlop);
+ return true;
}
- public static boolean isViewGroupToBottom(ViewGroup viewGroup) {
- View subChildView = viewGroup.getChildAt(0);
- return (subChildView != null && subChildView.getMeasuredHeight() <= viewGroup.getScrollY() + viewGroup.getHeight());
+ public static boolean isViewGroupToBottom(PageSlider viewGroup) {
+ Component subChildView = viewGroup.getComponentAt(0);
+ return (subChildView != null && subChildView.getEstimatedHeight() <= viewGroup.getScaleY() + viewGroup.getHeight());
}
public static boolean isScrollViewToBottom(ScrollView scrollView) {
if (scrollView != null) {
- int scrollContentHeight = scrollView.getScrollY() + scrollView.getMeasuredHeight() - scrollView.getPaddingTop() - scrollView.getPaddingBottom();
- int realContentHeight = scrollView.getChildAt(0).getMeasuredHeight();
+ int scrollContentHeight = (int) (scrollView.getScaleY() + scrollView.getEstimatedHeight() -
+ scrollView.getPaddingTop() - scrollView.getPaddingBottom());
+ int realContentHeight = scrollView.getComponentAt(0).getEstimatedHeight();
if (scrollContentHeight == realContentHeight) {
return true;
}
@@ -197,56 +169,27 @@ public class ScrollingUtil {
return false;
}
- public static boolean isAbsListViewToBottom(AbsListView absListView) {
- if (absListView != null && absListView.getAdapter() != null && absListView.getChildCount() > 0 && absListView.getLastVisiblePosition() == absListView.getAdapter().getCount() - 1) {
- View lastChild = absListView.getChildAt(absListView.getChildCount() - 1);
+ public static boolean isAbsListViewToBottom(ListContainer absListView) {
+ if (absListView != null && absListView.getChildCount() > 0
+ && absListView.getFirstVisibleItemPosition() == absListView.getChildCount() - 1) {
+ Component lastChild = absListView.getComponentAt(absListView.getChildCount() - 1);
- return lastChild.getBottom() <= absListView.getMeasuredHeight();
+ return lastChild.getBottom() <= absListView.getEstimatedHeight();
}
return false;
}
- public static boolean isRecyclerViewToBottom(RecyclerView recyclerView) {
+ public static boolean isRecyclerViewToBottom(ListContainer recyclerView) {
if (recyclerView != null) {
- RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
- if (manager == null || manager.getItemCount() == 0) {
- return false;
- }
-
- if (manager instanceof LinearLayoutManager) {
- // 处理item高度超过一屏幕时的情况
- View lastVisibleChild = recyclerView.getChildAt(recyclerView.getChildCount() - 1);
- if (lastVisibleChild != null && lastVisibleChild.getMeasuredHeight() >= recyclerView.getMeasuredHeight()) {
- if (android.os.Build.VERSION.SDK_INT < 14) {
- return !(ViewCompat.canScrollVertically(recyclerView, 1) || recyclerView.getScrollY() < 0);
- } else {
- return !ViewCompat.canScrollVertically(recyclerView, 1);
- }
- }
-
- LinearLayoutManager layoutManager = (LinearLayoutManager) manager;
- if (layoutManager.findLastCompletelyVisibleItemPosition() == layoutManager.getItemCount() - 1) {
- return true;
- }
- } else if (manager instanceof StaggeredGridLayoutManager) {
- StaggeredGridLayoutManager layoutManager = (StaggeredGridLayoutManager) manager;
-
- int[] out = layoutManager.findLastCompletelyVisibleItemPositions(null);
- int lastPosition = layoutManager.getItemCount() - 1;
- for (int position : out) {
- if (position == lastPosition) {
- return true;
- }
- }
- }
+ ComponentContainer.LayoutConfig manager = recyclerView.getLayoutConfig();
}
return false;
}
- public static void scrollAViewBy(View view, int height) {
- if (view instanceof RecyclerView) ((RecyclerView) view).scrollBy(0, height);
- else if (view instanceof ScrollView) ((ScrollView) view).smoothScrollBy(0, height);
- else if (view instanceof AbsListView) ((AbsListView) view).smoothScrollBy(height, 0);
+ public static void scrollAViewBy(Component view, int height) {
+ if (view instanceof ListContainer) ((ListContainer) view).scrollBy(0, height);
+ else if (view instanceof ScrollView) ((ScrollView) view).scrollBy(0, height);
+ else if (view instanceof ListContainer) ((ListContainer) view).scrollBy(height, 0);
else {
try {
Method method = view.getClass().getDeclaredMethod("smoothScrollBy", Integer.class, Integer.class);
@@ -259,53 +202,22 @@ public class ScrollingUtil {
public static void scrollToBottom(final ScrollView scrollView) {
- if (scrollView != null) {
- scrollView.post(new Runnable() {
- @Override
- public void run() {
- scrollView.fullScroll(ScrollView.FOCUS_DOWN);
- }
- });
- }
}
- public static void scrollToBottom(final AbsListView absListView) {
- if (absListView != null) {
- if (absListView.getAdapter() != null && absListView.getAdapter().getCount() > 0) {
- absListView.post(new Runnable() {
- @Override
- public void run() {
- absListView.setSelection(absListView.getAdapter().getCount() - 1);
- }
- });
- }
- }
- }
-
- public static void scrollToBottom(final RecyclerView recyclerView) {
- if (recyclerView != null) {
- if (recyclerView.getAdapter() != null && recyclerView.getAdapter().getItemCount() > 0) {
- recyclerView.post(new Runnable() {
- @Override
- public void run() {
- recyclerView.smoothScrollToPosition(recyclerView.getAdapter().getItemCount() - 1);
- }
- });
- }
- }
+ public static void scrollToBottom(final ListContainer absListView) {
}
- public static void scrollToBottom(View view) {
- if (view instanceof RecyclerView) scrollToBottom((RecyclerView) view);
- if (view instanceof AbsListView) scrollToBottom((AbsListView) view);
+ public static void scrollToBottom(Component view) {
+ if (view instanceof ListContainer) scrollToBottom((ListContainer) view);
+ if (view instanceof ListContainer) scrollToBottom((ListContainer) view);
if (view instanceof ScrollView) scrollToBottom((ScrollView) view);
}
public static int getScreenHeight(Context context) {
- WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- DisplayMetrics dm = new DisplayMetrics();
- windowManager.getDefaultDisplay().getMetrics(dm);
- return dm.heightPixels;
+ Optional
+ display = DisplayManager.getInstance().getDefaultDisplay(context);
+ DisplayAttributes displayAttributes = display.get().getAttributes();
+ return displayAttributes.height;
}
}
\ No newline at end of file
diff --git a/library/src/main/res/drawable/anim_loading_view.xml b/library/src/main/res/drawable/anim_loading_view.xml
deleted file mode 100644
index fabdfbacbf457dc7f91078e9bd8697dd628cb308..0000000000000000000000000000000000000000
--- a/library/src/main/res/drawable/anim_loading_view.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/library/src/main/res/layout/view_bezier.xml b/library/src/main/res/layout/view_bezier.xml
deleted file mode 100755
index cd0390d22ac56331ef9ede071fca182cfa374749..0000000000000000000000000000000000000000
--- a/library/src/main/res/layout/view_bezier.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/library/src/main/res/layout/view_sinaheader.xml b/library/src/main/res/layout/view_sinaheader.xml
deleted file mode 100644
index d804eaf7a703a6c701f8327a1ac6318087ceb837..0000000000000000000000000000000000000000
--- a/library/src/main/res/layout/view_sinaheader.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml
deleted file mode 100644
index 34ff483c66c11ff026a19cb7239dca47461e3882..0000000000000000000000000000000000000000
--- a/library/src/main/res/values/attrs.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/library/src/main/res/values/colors.xml b/library/src/main/res/values/colors.xml
deleted file mode 100644
index d882997634fc31e16debd436982eeee540876c3f..0000000000000000000000000000000000000000
--- a/library/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- #e75946
- #f4d227
- #4674e7
- #0ba62c
-
\ No newline at end of file
diff --git a/library/src/main/res/values/ids.xml b/library/src/main/res/values/ids.xml
deleted file mode 100644
index 7a383c93d3d3a465fba8d59cf06d6ad1ca3fc273..0000000000000000000000000000000000000000
--- a/library/src/main/res/values/ids.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/library/src/main/res/values/strings.xml b/library/src/main/res/values/strings.xml
deleted file mode 100644
index 6d5185635a623090a0a12f580fa101b4acbfbc92..0000000000000000000000000000000000000000
--- a/library/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- Library
-
diff --git a/library/src/main/resources/base/element/color.json b/library/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..1baa3d6eeffde00ada40e55525bc33505e6aa225
--- /dev/null
+++ b/library/src/main/resources/base/element/color.json
@@ -0,0 +1,20 @@
+{
+ "color": [
+ {
+ "name": "Orange",
+ "value": "#e75946"
+ },
+ {
+ "name": "Yellow",
+ "value": "#f4d227"
+ },
+ {
+ "name": "Blue",
+ "value": "#4674e7"
+ },
+ {
+ "name": "Green",
+ "value": "#0ba62c"
+ }
+ ]
+}
diff --git a/library/src/main/resources/base/element/string.json b/library/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..ea642c85c0facb2291cb11d8f87c8b135e602d3c
--- /dev/null
+++ b/library/src/main/resources/base/element/string.json
@@ -0,0 +1,24 @@
+{
+ "string": [
+ {
+ "name": "library_library",
+ "value": "library_library"
+ },
+ {
+ "name": "app_name",
+ "value": "xrecyclerview"
+ },
+ {
+ "name": "xr_listview_loading",
+ "value": "正在加载..."
+ },
+ {
+ "name": "xr_nomore_loading",
+ "value": "没有了"
+ },
+ {
+ "name": "xr_loading_done",
+ "value": "加载完成"
+ }
+ ]
+}
diff --git a/library/src/main/resources/base/graphic/anim_loading_view.xml b/library/src/main/resources/base/graphic/anim_loading_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7a5ee254584a2e24f95b9805fe433f7d173f5bd6
--- /dev/null
+++ b/library/src/main/resources/base/graphic/anim_loading_view.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/graphic/circle_button_ele.xml b/library/src/main/resources/base/graphic/circle_button_ele.xml
new file mode 100644
index 0000000000000000000000000000000000000000..06f6af96eb6694726c8e07371564187a13d1dc18
--- /dev/null
+++ b/library/src/main/resources/base/graphic/circle_button_ele.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
diff --git a/library/src/main/resources/base/graphic/circle_button_element.xml b/library/src/main/resources/base/graphic/circle_button_element.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c1a788a4001a68126440d8d0f6b3ce4cebfe2969
--- /dev/null
+++ b/library/src/main/resources/base/graphic/circle_button_element.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/graphic/circle_button_gray.xml b/library/src/main/resources/base/graphic/circle_button_gray.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ed21a4a43d7ebffec039d67ef8f1f3d7104f7b35
--- /dev/null
+++ b/library/src/main/resources/base/graphic/circle_button_gray.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/graphic/cricle_background.xml b/library/src/main/resources/base/graphic/cricle_background.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2d47f21b2404d0615f6c05d905d2e4f13a3e8c57
--- /dev/null
+++ b/library/src/main/resources/base/graphic/cricle_background.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/graphic/cricle_bg.xml b/library/src/main/resources/base/graphic/cricle_bg.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a7bfb83443873ff0fdb1f39c7eb32ad5e0528665
--- /dev/null
+++ b/library/src/main/resources/base/graphic/cricle_bg.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/graphic/cricle_redbg.xml b/library/src/main/resources/base/graphic/cricle_redbg.xml
new file mode 100644
index 0000000000000000000000000000000000000000..85ff2bb8c7b196dfdb7ea297dd9435df71ce3d38
--- /dev/null
+++ b/library/src/main/resources/base/graphic/cricle_redbg.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/graphic/toast_bg.xml b/library/src/main/resources/base/graphic/toast_bg.xml
new file mode 100644
index 0000000000000000000000000000000000000000..57367165e88fef285782519d5274cdaf659a9d38
--- /dev/null
+++ b/library/src/main/resources/base/graphic/toast_bg.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/layout/bottom_animation.xml b/library/src/main/resources/base/layout/bottom_animation.xml
new file mode 100644
index 0000000000000000000000000000000000000000..346bc4901055e5c65eb7222001e82b33aef5200f
--- /dev/null
+++ b/library/src/main/resources/base/layout/bottom_animation.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/layout/bottom_animation2.xml b/library/src/main/resources/base/layout/bottom_animation2.xml
new file mode 100644
index 0000000000000000000000000000000000000000..15ce984de65cfd50e1f4b82a32e6ad527e57f795
--- /dev/null
+++ b/library/src/main/resources/base/layout/bottom_animation2.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/layout/head_animation.xml b/library/src/main/resources/base/layout/head_animation.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c9a50d93f4cac5723c382a45d2bc8ad8413392b9
--- /dev/null
+++ b/library/src/main/resources/base/layout/head_animation.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/layout/layout_toast.xml b/library/src/main/resources/base/layout/layout_toast.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3e74ee89ae1122cb2536dd5c73446b5300844538
--- /dev/null
+++ b/library/src/main/resources/base/layout/layout_toast.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/layout/listview_header.xml b/library/src/main/resources/base/layout/listview_header.xml
new file mode 100644
index 0000000000000000000000000000000000000000..87472db8d3dfe94bace86110f88e3ac0af4cab54
--- /dev/null
+++ b/library/src/main/resources/base/layout/listview_header.xml
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/layout/view_bezier.xml b/library/src/main/resources/base/layout/view_bezier.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eb2ab958b3dfac14b9cc5a9eee72600b5f713302
--- /dev/null
+++ b/library/src/main/resources/base/layout/view_bezier.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/layout/view_sinaheader.xml b/library/src/main/resources/base/layout/view_sinaheader.xml
new file mode 100644
index 0000000000000000000000000000000000000000..459d66b9a73fb8eef0ec34312db77606dfab80ac
--- /dev/null
+++ b/library/src/main/resources/base/layout/view_sinaheader.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/resources/base/media/circle1.png b/library/src/main/resources/base/media/circle1.png
new file mode 100644
index 0000000000000000000000000000000000000000..06a093af8555667b99c06703f5cbfaefbe8a28b5
Binary files /dev/null and b/library/src/main/resources/base/media/circle1.png differ
diff --git a/library/src/main/resources/base/media/circle2.png b/library/src/main/resources/base/media/circle2.png
new file mode 100644
index 0000000000000000000000000000000000000000..5c3c0ac421f67153d863746d335d214db8d88b32
Binary files /dev/null and b/library/src/main/resources/base/media/circle2.png differ
diff --git a/library/src/main/resources/base/media/circle3.png b/library/src/main/resources/base/media/circle3.png
new file mode 100644
index 0000000000000000000000000000000000000000..6048094f1d870bf6e8e912978c1af4d17242202f
Binary files /dev/null and b/library/src/main/resources/base/media/circle3.png differ
diff --git a/library/src/main/resources/base/media/circle4.png b/library/src/main/resources/base/media/circle4.png
new file mode 100644
index 0000000000000000000000000000000000000000..d5e8f57be604e14ba37ba8bde08e3549ce3dd317
Binary files /dev/null and b/library/src/main/resources/base/media/circle4.png differ
diff --git a/library/src/main/res/drawable-xhdpi/ic_arrow.png b/library/src/main/resources/base/media/ic_arrow.png
similarity index 100%
rename from library/src/main/res/drawable-xhdpi/ic_arrow.png
rename to library/src/main/resources/base/media/ic_arrow.png
diff --git a/library/src/main/resources/base/media/ic_loading_rotate.png b/library/src/main/resources/base/media/ic_loading_rotate.png
new file mode 100644
index 0000000000000000000000000000000000000000..f0a4bfebd93114778e16e12990eebb8bd67421a1
Binary files /dev/null and b/library/src/main/resources/base/media/ic_loading_rotate.png differ
diff --git a/library/src/main/resources/base/media/ic_pulltorefresh_arrow.png b/library/src/main/resources/base/media/ic_pulltorefresh_arrow.png
new file mode 100644
index 0000000000000000000000000000000000000000..511fa3197b538b8500a22d22280e6f33085d9491
Binary files /dev/null and b/library/src/main/resources/base/media/ic_pulltorefresh_arrow.png differ
diff --git a/library/src/main/resources/base/media/refresh.png b/library/src/main/resources/base/media/refresh.png
new file mode 100644
index 0000000000000000000000000000000000000000..78369b57f38b9976b9020757958d7b9cf3c1e4af
Binary files /dev/null and b/library/src/main/resources/base/media/refresh.png differ
diff --git a/library/src/main/res/mipmap-hdpi/refresh_head_arrow.png b/library/src/main/resources/base/media/refresh_head_arrow.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_head_arrow.png
rename to library/src/main/resources/base/media/refresh_head_arrow.png
diff --git a/library/src/main/res/mipmap-hdpi/refresh_loading01.png b/library/src/main/resources/base/media/refresh_loading01.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_loading01.png
rename to library/src/main/resources/base/media/refresh_loading01.png
diff --git a/library/src/main/res/mipmap-hdpi/refresh_loading02.png b/library/src/main/resources/base/media/refresh_loading02.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_loading02.png
rename to library/src/main/resources/base/media/refresh_loading02.png
diff --git a/library/src/main/res/mipmap-hdpi/refresh_loading03.png b/library/src/main/resources/base/media/refresh_loading03.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_loading03.png
rename to library/src/main/resources/base/media/refresh_loading03.png
diff --git a/library/src/main/res/mipmap-hdpi/refresh_loading04.png b/library/src/main/resources/base/media/refresh_loading04.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_loading04.png
rename to library/src/main/resources/base/media/refresh_loading04.png
diff --git a/library/src/main/res/mipmap-hdpi/refresh_loading05.png b/library/src/main/resources/base/media/refresh_loading05.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_loading05.png
rename to library/src/main/resources/base/media/refresh_loading05.png
diff --git a/library/src/main/res/mipmap-hdpi/refresh_loading06.png b/library/src/main/resources/base/media/refresh_loading06.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_loading06.png
rename to library/src/main/resources/base/media/refresh_loading06.png
diff --git a/library/src/main/res/mipmap-hdpi/refresh_loading07.png b/library/src/main/resources/base/media/refresh_loading07.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_loading07.png
rename to library/src/main/resources/base/media/refresh_loading07.png
diff --git a/library/src/main/res/mipmap-hdpi/refresh_loading08.png b/library/src/main/resources/base/media/refresh_loading08.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_loading08.png
rename to library/src/main/resources/base/media/refresh_loading08.png
diff --git a/library/src/main/res/mipmap-hdpi/refresh_loading09.png b/library/src/main/resources/base/media/refresh_loading09.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_loading09.png
rename to library/src/main/resources/base/media/refresh_loading09.png
diff --git a/library/src/main/res/mipmap-hdpi/refresh_loading10.png b/library/src/main/resources/base/media/refresh_loading10.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_loading10.png
rename to library/src/main/resources/base/media/refresh_loading10.png
diff --git a/library/src/main/res/mipmap-hdpi/refresh_loading11.png b/library/src/main/resources/base/media/refresh_loading11.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_loading11.png
rename to library/src/main/resources/base/media/refresh_loading11.png
diff --git a/library/src/main/res/mipmap-hdpi/refresh_loading12.png b/library/src/main/resources/base/media/refresh_loading12.png
old mode 100755
new mode 100644
similarity index 100%
rename from library/src/main/res/mipmap-hdpi/refresh_loading12.png
rename to library/src/main/resources/base/media/refresh_loading12.png
diff --git a/library/src/main/resources/base/media/yuanxing.png b/library/src/main/resources/base/media/yuanxing.png
new file mode 100644
index 0000000000000000000000000000000000000000..6606fbd4270275b153d9e10663e2ec6e6cc3442f
Binary files /dev/null and b/library/src/main/resources/base/media/yuanxing.png differ
diff --git a/library/src/test/java/com/lcodecore/tkrefreshlayout/ExampleTest.java b/library/src/test/java/com/lcodecore/tkrefreshlayout/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1bdc0410896e08f3a1ad75da0547d56ea4820d3
--- /dev/null
+++ b/library/src/test/java/com/lcodecore/tkrefreshlayout/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.lcodecore.tkrefreshlayout;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/settings.gradle b/settings.gradle
index 662d1551f0bf63db91c533ab810519f76292ece6..d0c7ee8440156d4a9324ac5357770747425fef57 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':app', ':library'
+include ':entry', ':library'