The TwinklingRefreshLayout extends Google’s SwipeRefreshLayout idea by not cutting on the list controls, but using a ViewGroup to contain the list controls to keep them low coupling and versatile. Its main features are:

  1. Support RecyclerView, ScrollView, AbsListView series (ListView, GridView), WebView and other controls that can get scrollY
  2. Support for loading more
  3. Default support for out-of-bounds rebound
  4. Enable clean out-of-bounds rebound mode with no refresh control
  5. SetOnRefreshListener has a number of methods that can be called back
  6. Header and Footer are abstracted as interfaces, and coefficients in the sliding process are called back to make it easy to personalize Header and Footer

Demo

Download the Demo

Method of use

2. Add TwinklingRefreshLayout to the XML




    
Copy the code

TwinklingRefreshLayout does not automatically end up refreshing or loading more, requiring manual control
refreshLayout.setOnRefreshListener(new TwinklingRefreshLayout.OnRefreshListener(){
            @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);
            }
        });
    }Copy the code

Finish the refresh using the finishRefreshing() method and finish loading more using the finishLoadmore() method. There are other methods for OnRefreshListener here, and you can override them as needed.

SetHeaderView (IHeaderView, headerView), setBottomView(IBottomView, bottomView)

Set the header/bottom personalization refresh effect. The header needs to implement IHeaderView, and the bottom needs to implement IBottomView.

setPureScrollModeOn()

Turn on the pure bounding rebound mode, that is, all views related to refresh are not displayed, only the bounding rebound effect is displayed

Other instructions

2. SetOnRefreshListener A number of callback methods

  • OnPullingDown (TwinklingRefreshLayout refreshLayout, Float Fraction) is being pulled down
  • OnPullingUp (TwinklingRefreshLayout refreshLayout, Float Fraction) is being pulled up
  • OnPullDownReleasing (TwinklingRefreshLayout refreshLayout, float Fraction) Drop down release process
  • OnPullUpReleasing (TwinklingRefreshLayout refreshLayout, Float Fraction) PulluPreLeasing (TwinklingRefreshLayout, Float Fraction
  • OnRefresh (TwinklingRefreshLayout refreshLayout) is refreshing
  • OnLoadMore (TwinklingRefreshLayout refreshLayout) is loading more

Fraction represents the ratio of the current pull-down distance to the Header height (or the ratio of the current pull-up distance to the Footer height).

3. Implement personalized headers and footers

The relevant interfaces are IHeaderView and IBottomView respectively, and the codes are as follows:

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);
}Copy the code

The getView() method is used to get the actual Header in TwinklingRefreshLayout, so null cannot be returned.

To achieve the refresh effect like Sina Weibo, the implementation code is as follows:

1. First define SinaRefreshHeader inherits from FrameLayout and implements IHeaderView

2. The getView() method returns this

3. Get the layout you need in the onAttachedToWindow() method

@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); }}Copy the code

4. Implement other 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);
    }Copy the code

5. Layout files



    

    

    
Copy the code

Refresharrow.setrotation (fraction * headHeight/maxHeadHeight * 180) Fraction * headHeight represents the current sliding distance of the head, then calculate the ratio of this to the maximum height, then multiply by 180, so that when the Arrow reaches the maximum sliding distance, the Arrow will rotate exactly 180 degrees.

OnPullingDown/onPullingUp said is dropdown/is on the drawing process. OnPullReleasing indicates the state of the callback when pulling up/down. StartAnim is called back after onRefresh/onLoadMore.

As shown above, it's easy to implement a personalized Header or Footer. For a simpler implementation, see TextHeaderView in Demo (Figure 4).