RefreshLayout that support for OverScroll and better than iOS. 支持下拉刷新和上拉加载的RefreshLayout,自带越界回弹效果,支持RecyclerView,AbsListView,ScrollView,WebView
APACHE-2.0 License
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.
Any View is supported.
You can download these Videos for more details.
compile 'com.lcodecorex:tkrefreshlayout:1.0.7'
<?xml version="1.0" encoding="utf-8"?>
<com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:tr_wave_height="180dp"
app:tr_head_height="100dp">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:background="#fff" />
</com.lcodecore.library.TwinklingRefreshLayout>
To get better effect, you'd better add code android:overScrollMode="never"
to the childView.
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().
And now dp value is supported.
Flexible settings for whether to disable the pulling-down mode.
Whether to allow overscroll mode, opened by default.
Whether to allow the display refresh control on overscrolling, the default is true.
To open the pure overscroll mode so that refreshView would gone permanently.
if open the loadmore mode after overscrolling bottom automatically.
Allow you to add a view fixed on the top.
Make refresh-animation like SwipeRefreshLayout.
Set the target view that you can scroll.
static methods aims to set a default header/footer in a/an Application/Activity.
fraction = currentMoveHeight/headHeight OR (fraction = currentMoveHeight/bottomHeight).
####Footer
Here is more animations.AVLoadingIndicatorView。
The Header needs to implement IHeaderView interface and Footer in in the same way(IBottomView).
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() method is not allow to return null.
1.Define SinaRefreshHeader extended from FrameLayout and implement IHeaderView interface.
2.Return this in the method getView().
3.Inflate and find Views in the layout xml.
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);
}
}
4.Override some methods.
@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.layout xml.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ImageView
android:id="@+id/iv_arrow"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_arrow"/>
<ImageView
android:id="@+id/iv_loading"
android:visibility="gone"
android:layout_width="34dp"
android:layout_height="34dp"
android:src="@drawable/anim_loading_view"/>
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:textSize="16sp"
android:text="pull down to refresh"/>
</LinearLayout>
Pay attention to the using of the parameter fraction
. Such as the code aboverefreshArrow.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))。
---layout
<?xml version="1.0" encoding="utf-8"?>
<com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coord_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:addStatesFromChildren="true"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false">
<!--...-->
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
</com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout>
--- code1
refreshLayout.setTargetView(rv);
Find the RecyclerView/ListView.
--- code2
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);
}
}
});
####CoordinatorLayout nested TwinklingRefreshLayout --- layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coord_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:addStatesFromChildren="true"
android:fitsSystemWindows="true">
<com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout
android:id="@+id/refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
Pay attention to layout_behavior="@string/appbar_scrolling_view_behavior"
for TwinklingRefreshLayout.
ps:Contact me: [email protected] QQ group: 202640706
If you like this library, you can donate me. Buy me a coffee!
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.