Github source address: https://github.com/zhou-you/EasyXRecyclerView

preface

Some time ago there was published an article EasyXRecyclerView library based on RecyclerView ultimate packaging (a) – introduction, this article is the second article in this series is mainly explained and library related XRecyclerView supported functions and extensions.

XRecyclerView usage introduction

XRecyclerView based on RecyclerView packaging, on the basis of the original function support refresh, load more, custom refresh load more, add head, tail and so on

Add (single/multiple)HeaderViw and FooterView

You can add a single or multiple plain HeaderViw and FooterView to support the LinearLayoutManager and GridLayoutManager. A:

/ / add a header view mRecyclerView. AddHeaderView (new SampleHeader (this)); //mRecyclerView.addHeaderView(new SampleHeader2(this)); // Add the second header view.... //mRecyclerView.addHeaderView(new SampleHeaderN(this)); The view / / add the NTH head (head) / / add a rear view mRecyclerView. AddFooterView (new SampleFooter (this)); //mRecyclerView.addFooterView(new SampleFooter2(this)); // Add a second tail view.... //mRecyclerView.addFooterView(new SampleFooterN(this)); // Add NTH tail viewCopy the code

Method 2:

Public view headerView = layoutinflater.from (this).inflate(r.layout.layout_header, (ViewGroup)findViewById(android.R.id.content),false); mRecyclerView.addHeaderView(headerView); //mRecyclerView.addHeaderView(headerView2); // Add the second header view... //mRecyclerView.addHeaderView(headerViewN); // add the NTH headerView (multiple headers) // click the event headerview.findviewbyid (r.id.test_txt).setonclicklistener (new view).OnClickListener() { @Override public void onClick(View v) { ... }}); // Add a tail view view footerView = getLayoutInflater().inflate(r.layout.layout_footer, (ViewGroup) mRecyclerView.getParent(),false); mRecyclerView.addFooterView(footerView); //mRecyclerView.addFooterView(footerView2); // Add a second tail view.... //mRecyclerView.addFooterView(footerViewN); // Add the NTH tail view (multiple tails) // Click the event footerView.findViewById(R.id.test_txt).setonClickListener (new View).OnClickListener() { @Override public void onClick(View v) { ... }});Copy the code

Note: This feature just adds normal headers and tails, not the same as refreshing and loading more headers and tails, remember! Display issues of refreshing headers and loading more tails are not affected

Remove HeaderViw and FooterView

/ / remove add head view mRecyclerView. RemoveHeaderView (headerView); / / remove the tail end of the add view mRecyclerView. RemoveFooterView (footerView);Copy the code

Drop-down refresh and load more style

/ / set the style of the drop-down refresh Progress mRecyclerView setRefreshProgressStyle (ProgressStyle. BallSpinFadeLoader); / / in ProgressStyle choose the style of the refresh / / set the drop-down arrow mRecyclerView. SetArrowImageView (R.d rawable. Iconfont_downgrey); / / set the style of the load more Progress mRecyclerView setLoadingMoreProgressStyle (ProgressStyle. BallPulse);Copy the code

Note: 1. If you use a custom drop down to refresh setRefreshHeader() and load more setLoadingMoreFoote(), the above Settings will not work and do not need to be set.

Enable and disable the drop-down refresh and load more functions

/ / open the refresh and load more mRecyclerView setPullRefreshEnabled (true);
mRecyclerView.setLoadingMoreEnabled(true);
Copy the code

Note: It is enabled by default.

Set bottom loading text prompt

mRecyclerView.setFootViewText("Loading like hell."."All of it.");
Copy the code

Note: This setting does not work when customizing more views, remember!

The drop-down refresh is complete

 mRecyclerView.refreshComplete();
Copy the code

Pull up loading more complete

 mRecyclerView.loadMoreComplete();
Copy the code

Data loading completed

 mRecyclerView.setNoMore(true);
Copy the code

Enable Automatic page refresh

mRecyclerView.setRefreshing(true); // No more dataCopy the code

Example: Enter the page automatically in Acitvity and handle in onStart().

@Override
protected void onStart() {
    super.onStart();
    if(mRecyclerView ! =null){ mRecyclerView.setRefreshing(true); }}Copy the code

Customize drop-down refresh View

  1. Custom view inherit BaseRefreshHeader;
  2. Call setRefreshHeader(IRefreshHeader refreshHeader).
 mRecyclerView.setRefreshHeader(new CustomRefreshHeader(this));
Copy the code

Example:

public class CustomRefreshHeader extends BaseRefreshHeader {
    private CustomAnimView mCustomAnimView;
    public CustomRefreshHeader2(Context context) {
        super(context);
    }

    public CustomRefreshHeader2(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public View getViewMCustomAnimView = new CustomAnimView(getContext());returnmCustomAnimView; // Method two //returnLayoutInflater.from(getContext()).inflate(R.layout.clife_loading_header,null); } // Override public void OverridesetState(int state) { super.setState(state); STATE_NORMAL, STATE_RELEASE_TO_REFRESH, STATE_REFRESHING, STATE_REFRESHING, STATE_DONE.if(state = = STATE_REFRESHING) {/ / / / show schedule here to deal with their own logic, refresh the mCustomAnimView. StartAnim (); }else if(state == STATE_DONE) {// Here to handle your logic and refresh McUstomanimview.stopanim (); }else {
            mCustomAnimView.startAnim();
        }
    }
    

   /* @Override
    public void refreshComplete() {// There is a default handler that can override this method handler, }*/ * @override public void smoothScrollTo(int destHeight) {// super.smoothScrollto (destHeight); }*/ / More methods can be implemented by overwriting, customizing}Copy the code

Note: setRefreshProgressStyle () does not work if you set a custom pull-refresh. You do not need to configure it, either using the default style Settings supported by the library or using a custom View.

Customize loading more views

  1. Custom view implementation BaseMoreFooter interface;
  2. Call setLoadingMoreFooter(IMoreFooter refreshHeader).
 mRecyclerView.setLoadingMoreFooter(new CustomMoreFooter(this));
Copy the code

Example:

public class CustomMoreFooter extends BaseMoreFooter {
    private AnimationDrawable mAnimationDrawable;
    private LinearLayout allLayout;
    private TextView mTextView;

    public CustomMoreFooter(Context context) {
        super(context);
    }

    public CustomMoreFooter(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void initView() { super.initView(); // Display super.initView(); allLayout = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.pull_to_refresh_clife, null); ImageView imageView = (ImageView) allLayout.findViewById(R.id.lodimg); imageView.setImageResource(R.drawable.icon_loading_animation); mAnimationDrawable = (AnimationDrawable) imageView.getDrawable(); mTextView = (TextView) allLayout.findViewById(R.id.lodtext); addView(allLayout); } @Override public voidsetState(int state) { super.setState(state); // The following are the state judgments I need to customize the animation, you can choose according to your own needs. STATE_LOADING, STATE_COMPLETE, STATE_NOMORE, STATE_NOMORE switch (state) {case STATE_LOADING:
                this.setVisibility(View.VISIBLE);
                mAnimationDrawable.start();
                mTextView.setText("Trying to load...");
                mTextView.setVisibility(VISIBLE);
                break;
            case STATE_COMPLETE:
                this.setVisibility(View.GONE);
                mAnimationDrawable.stop();
                mTextView.setText("Load complete");
                break;
            case STATE_NOMORE:
                mAnimationDrawable.stop();
                mTextView.setText("No more");
                this.setVisibility(View.GONE);
                break; }}}Copy the code

Note: setRefreshProgressStyle () does not work if you set a custom pull-refresh. You do not need to configure it, either using the default style Settings supported by the library or using a custom View.

Slide and load more event listeners

mRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {
    @Override
    public void onRefresh() {// drop refresh... } @Override public voidonLoadMore() {// Load more... }});Copy the code

Set the dividing line

Line can use libraries provide custom universal line HorizontalDividerItemDecoration and XHorizontalDividerItemDecoration, here only do use introduction, a detailed look at the demo sample on line.

/ / case 1 recyclerView. AddItemDecoration (new HorizontalDividerItemDecoration. Builder (this). The build ()); / / case 2 recyclerView. AddItemDecoration (new HorizontalDividerItemDecoration. Builder (this). Paint (paint) margin (15) .showLastDivider() .build()); / / in 3 recyclerView addItemDecoration (new com. Zhouyou. RecyclerView. Divider. HorizontalDividerItemDecoration. Builder (this) //.drawable(r.drawable.divider_sample)//.9 figure.drawable (r.drawable.divider_Shape)// Shape file.size (10).build()); // example 4 Paint Paint = new Paint(); paint.setStrokeWidth(5); paint.setColor(Color.BLUE); paint.setAntiAlias(true);
        paint.setPathEffect(new DashPathEffect(new float[] {f 15.0, 15.0} f, 0)); recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(this) .paint(paint) .margin(15) .startSkipCount(2) .endSkipCount(2) .build()); . // See sectionline for more informationCopy the code

Note: This partition line is mainly used for LinearLayoutManager, poor support for GridLayoutManager and StaggeredGridAdapter, for this kind of partition line needs to be customized.

Set the side slide menu

To set the SwipeMenuRecyclerView, you need to use custom SwipeMenuRecyclerView. This view is inherited from XRecyclerView and has all the functions and properties of XRecyclerView. 1. Reference SwipeMenuRecyclerView for Xml layout

 <com.zhouyou.recyclerview.swipemenu.SwipeMenuRecyclerView
        android:id="@+id/super_swipemenu_recycle_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
Copy the code

2. SwipeMenuLayout is used for item layout files, but there are no special requirements on adapters. For example: adapter_menu_layout_item. XML

<? xml version="1.0" encoding="utf-8"? > <! - the outer layout must use SwipeMenuLayout - > <. Com. Zhouyou recyclerview. Swipemenu. SwipeMenuLayout XMLNS: android ="http://schemas.android.com/apk/res/android"
                                                    android:layout_width="match_parent"
                                                    android:layout_height="wrap_content"> <! --> <include android:id= -- <include android:id="@+id/smContentView"
        layout="@layout/item_swipe_menu_content"/ > <! <include android:id= --> <include android:id="@+id/smMenuView"
        layout="@layout/item_swipe_menu1" />

</com.zhouyou.recyclerview.swipemenu.SwipeMenuLayout>
Copy the code

Note: For more information about SwipeMenuLayout, please refer to the demo.

Set sticky hover

There are two kinds of hover effects: one is StickyNavLayout, the other is StickyNestedScrollView (inherited from V4 package NestedScrollView extension). Why do you put these two hover effects in a library, Because XRecyclerView, StickyNavLayout/StickyNestedScrollView, Tablayout, ViewPager and HelperRecyclerViewAdapter will combine each other problems such as conflict, This library has solved the existing known compatibility problems, get through each other, on the other hand is also the collection of common functions of EasyXRecyclerView. StickyNavLayout

You can set the page of a control slide hover, the bottom content area support ScrollView, ListView,RecyclerView. Note the setting of the control ID

  • Top region: ID must be Android: ID =”@+ ID/ID_stickyNavLayout_topview”
  • Floating area: ID must be Android: ID =”@+ ID/ID_stickyNavLayout_indicator”
  • Content area: ID Must be Android: ID =”@+ ID/ID_stickyNavLayout_viewpager”

The content area

  • The content area must be ViewPager or a subclass
  • Android :id=”@+ ID/ID_stickyNavLayout_innerScrollView “android:id=”@+ ID/ID_stickyNavLayout_innerscrollView”

Introduce in XML:

<? xml version="1.0" encoding="utf-8"? > <com.zhouyou.recyclerview.sticky.StickyNavLayout android:id="@+id/id_stick"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:isStickNav="false"> <! The header layout ID must be set to id_stickyNavLayout_topview --> <LinearLayout Android: ID ="@id/id_stickynavlayout_topview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"> <! Write header content -->... </LinearLayout> <! The layout ID to hover must be set to id_stickyNavLayout_indicator --> <LinearLayout Android: ID ="@id/id_stickynavlayout_indicator". > <! Write hover area content -->... </LinearLayout> <! The ViewPager ID must be set to ID_stickyNavLayout_viewpager --> <! RecycleView, XRecycleView, id_stickyNavLayout_innerScrollView --> <android.support.v4.view.ViewPager android:id="@id/id_stickynavlayout_viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</com.zhouyou.recyclerview.sticky.StickyNavLayout>
Copy the code

Note: For more functions, please refer to hongyang Daishen’s explanation. StickyNestedScrollView

StickyNestedScrollView is easy to use and supports multiple hovers. You can set the tag attribute to sticky, sticky-nonconstant, or sticky-hastransparency. You can use the Android tag=”sticky”. Introduce in XML:

<? 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <com.zhouyou.recyclerview.sticky.StickyNestedScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"> <! --> <TextView... android:tag="sticky"
                android:text="A"/ > <! --> <TextView... android:text="B"/ > <! --C sets the tag to hover like A --> <TextView... android:tag="sticky"
            android:text="B"/>

        </LinearLayout>
    </com.zhouyou.recyclerview.sticky.StickyNestedScrollView>
</android.support.design.widget.CoordinatorLayout>
Copy the code

StickyNestedScrollView supports addOnViewStickyListener(OnViewStickyListener) StickyListener), removeOnViewStickyListener (OnViewStickyListener StickyListener), clearOnViewStickyListener (), setShadowHeight (int height), setShadowDrawable (Drawable shadowDrawable). If an item in the XRecyclerview adapter needs to hover, just set the item layout to Android: Tag =”sticky” to hover, but there is a problem with this. If you set it statically in XML, all items will hover. SetTag (“sticky”) can be dynamically set according to the business logic;

Compare StickyNavLayout to StickyNestedScrollView

  1. So StickyNavLayout is a little bit more cumbersome to use than StickyNestedScrollView, especially if you want to pay attention to the Id Settings, StickyNestedScrollView is a little bit easier to use.
  2. StickyNavLayout supports a single hover, StickyNestedScrollView supports multiple hover.
  3. StickyNestedScrollView is not suitable for nesting Recyclerview with refresh and load more, Recyclerview after nesting will fail to load more, and StickyNavLayout will not affect the loading and function.
  4. If the content is more recommended to use StickyNavLayout+Recyclerview to achieve the page with head hover list function, StickyNestedScrollView+Recyclerview can not load too much data, especially for paging. Because StickyNestedScrollView principle is to transfer the sliding events of Recyclerview to their own processing, so the Recyclerview reuse mechanism will not work, too much data is easy to OOM. If you have a single page and you don’t have a lot of data you can use StickyNestedScrollView and it’s a lot easier.

Note: For more complex hover scenarios, please refer to the Sticky section in demo.

Complete sample

All attribute Settings are set according to their own needs, do not need to set all attributes again, remember! Remember that! Remember that!

XRecyclerView mRecyclerView = (com.zhouyou.recyclerview.XRecyclerView) this.findViewById(R.id.recyclerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setAutoMeasureEnabled(true); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(layoutManager); Way / / refresh a choice: one way or two way / / a: adopt libraries provide the default refresh style mRecyclerView. SetRefreshProgressStyle (ProgressStyle. BallSpinFadeLoader); / / set the drop-down to refresh the Progress of style, inside the ProgressStyle. Choose favorite style mRecyclerView setArrowImageView (R.d rawable. Iconfont_downgrey); / / set the drop-down to refresh the arrow mRecyclerView. SetLoadingMoreProgressStyle (ProgressStyle. BallPulse); / / set the style of the load more Progress mRecyclerView setFootViewText ("Loading like hell."."All of it."); / / way 2: completely using custom refresh animation / / mRecyclerView setRefreshHeader (new CustomRefreshHeader (this)); //mRecyclerView.setLoadingMoreFooter(new CustomLoadingMoreFooter(this)); / / open the refresh and load more / / mRecyclerView setPullRefreshEnabled (true);
//mRecyclerView.setLoadingMoreEnabled(true); Public view headerView = layoutinflater.from (this).inflate(r.layout.layout_header, (ViewGroup)findViewById(android.R.id.content),false);
View footerView = getLayoutInflater().inflate(R.layout.layout_footer, (ViewGroup) mRecyclerView.getParent(), false); mRecyclerView.addHeaderView(headerView); mRecyclerView.addFooterView(footerView); / / line set mRecyclerView. AddItemDecoration (new HorizontalDividerItemDecoration. Builder (this). The build ()); / / remove add head view mRecyclerView. RemoveHeaderView (headerView); / / remove the tail end of the add view mRecyclerView. RemoveFooterView (footerView); mRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {
    @Override
    public void onRefresh() {/ / dropdown refresh / / mRecyclerView refreshComplete (); } @override public voidonLoadMore() {/ / loaded more / / mRecyclerView loadMoreComplete (); / / loading animation complete / / mRecyclerView setNoMore (true); // Data load complete}}); MyAdapter mAdapter = new MyAdapter(this); mRecyclerView.setAdapter(mAdapter); // This library unwritten rules, best to usesetAdapter write before loading data madapter.setListall (datas); // The action is placed onsetAfter the AdapterCopy the code