preface

series

This is the sixth article in the series, and here are the first five:

A general overview of playing Android from 0 to 1

2, play Android from 0 to 1 project home page

3. Play Android home page frame building from 0 to 1.

4. Thinking about the architecture of playing Android from 0 to 1

5, Play android from 0 to 1 adapter thinking

As usual, put the Github address and apK download address.

Apk download address: www.pgyer.com/llj2

Github address: github.com/zhujiang521…

Ins and outs

RecyclerView is usually used by everyone. In this project, the use method of RecyclerView is basically the following:

It’s basically a list of articles, including drop-down refresh and drop-down load, using the following library:

SmartRefreshLayout

Here are the library dependencies:

api  'com. Scwang. Smart: refresh layout - kernel: 2.0.1'      // The core must depend
api  'com. Scwang. Smart: refresh header - classics: 2.0.1'    // Classic refresh header
api  'com. Scwang. Smart: refresh - footer - classics: 2.0.1'    // Classic loading
Copy the code

How to use the library is described below, but you are advised to check out the documentation on Github.

Speaking of which, it’s time to get down to business! What function are we going to implement today?

The story happened last weekend, I was bored in the brush their own written play Android, in the latest some articles, brush for a long time, read a lot of entries, suddenly want to go back to the top, can only have been sliding, think about this is too inhumane bar! A lot of software have a key top function, is also very convenient, dry dry, then to play Android also add a key top function!

Let’s take a look at the final implementation effect!

Begin to implement

implementation

In fact, the core implementation is very simple, just need the following line of code:

mToTopRecycleView.smoothScrollToPosition(0)
Copy the code

I don’t have to explain that much.

The only time I’m going to show the top button is when you’re going up, not normally, not when you’re going down, not when you’re going up to the top. Why is that? Because I personally think the user has to slide up to prove that the user might want to go back to the top.

So let’s see how to set the display time!

mToTopRecycleView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
   override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
       if(! recyclerView.canScrollVertically(-1)) {
           // Slide up to the top
       } else if (dy < 0) {
           / / slide
       } else if (dy > 0) {
           / / decline in}}})Copy the code

This is pretty much all you need to do, just add a button to the layout and add a click event to the button. But…

However, if only one page needs to be placed on the top, it would be easy to add a button to the page layout, but the list of articles has many pages, not just one! And all have pull refresh and pull up the function of loading, in line with the lazy efforts of programmers, or write less, extract a control out of it, other places if you need to use directly with this control on the line! So get started!

The parent of this control should be a ViewGroup, which is not difficult to layout, so use FrameLayout.

class ToTopRecyclerView @JvmOverloads constructor(
    private val mContext: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FrameLayout(mContext, attrs, defStyleAttr)
Copy the code

Defining a class is more than half the battle. Why? All things are difficult before they are easy. What are you afraid of when you’ve opened your head!

Next load the layout in the init method:

init{
    View.inflate(mContext, R.layout.layout_to_top, this)}Copy the code

Take a look at the layout file:

<? xml version="1.0" encoding="utf-8"? > <merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.scwang.smart.refresh.layout.SmartRefreshLayout
        android:id="@+id/toTopSmartRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/toTopRecycleView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </com.scwang.smart.refresh.layout.SmartRefreshLayout>

    <ImageView
        android:id="@+id/toTopIvClick"
        android:layout_width="@dimen/dp_40"
        android:layout_height="@dimen/dp_40"
        android:layout_gravity="right|bottom"
        android:layout_margin="@dimen/dp_20"
        android:background="@drawable/to_top_bg"
        android:padding="@dimen/dp_8"
        android:src="@drawable/ic_baseline_vertical_align_top_24"
        android:visibility="gone" />

</merge>
Copy the code

Merge is a merge. Merge is a merge. Merge is a merge.

So here’s findViewById, which is too simple to post code and waste time.

Next, we need to think about what functions we want this control to complete. There are a total of the following functions:

  • Set the Adapter of RecyclerView
  • Set pull-up load and pull-down refresh events
  • Set RecyclerView LayoutManager

Some people might say, don’t you need a one-button top? What is the point of writing this control if we need to!

Let’s write them one by one in the order listed above.

Set the adapter of RecyclerView:

fun setAdapter(adapter: RecyclerView.Adapter<BaseListAdapter.ViewHolder>) {
    mToTopRecycleView.adapter = adapter
}
Copy the code

The code is simple and provides an entry to the external setting adapter.

Then there are the events that set the pull-up load and pull-down refresh:

fun onRefreshListener(onRefreshListener: () -> Unit, onLoadMoreListener: () -> Unit) {
    mToTopSmartRefreshLayout.apply {
        setOnRefreshListener { reLayout ->
            reLayout.finishRefresh(measureTimeMillis {
                onRefreshListener.invoke()
            }.toInt())
        }
        setOnLoadMoreListener { reLayout ->
            val time = measureTimeMillis {
                onLoadMoreListener.invoke()
            }.toInt()
            reLayout.finishLoadMore(if (time > mLoadTime) time else mLoadTime)
        }
    }
}
Copy the code

This method needs to be mentioned, and this is how the library is used at the beginning of this article.

This section uses a higher-order function. The method parameters are two functions. The first one is the refresh function, and the second one is the load more function.

Finally, the LayoutManager of RecyclerView was set. In order to save trouble, I decided to write this function to be more convenient. When calling it in other places, I only need to pass in Boolean value or int, and then set different LayoutManagers by judgment.

Reasoning, the project of RecyclerView only two LayoutManager, respectively is LinearLayoutManager (portrait) and StaggeredGridLayoutManager (landscape), Use Boolean values as arguments to determine which LayoutManager to use. Here is the code for this method:

fun setRecyclerViewLayoutManager(isLinearLayout: Boolean) {
    if (isLinearLayout) {
        mToTopRecycleView.layoutManager = LinearLayoutManager(context)
    } else {
        val spanCount = 2
        val layoutManager =
            StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.VERTICAL)
        mToTopRecycleView.layoutManager = layoutManager
        layoutManager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_NONE
    }
}
Copy the code

OK, that’s enough.

use

Implementation completed should be used, practice is the only standard to test truth!

Try the home page first and add it to the layout:

<com.zj.core.view.custom.ToTopRecyclerView
    android:id="@+id/homeToTopRecyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
Copy the code

Attention! The next call to write above!

homeToTopRecyclerView.setAdapter(articleAdapter)
homeToTopRecyclerView.onRefreshListener({
    page = 1
    getArticleList(true)
}, {
    page++
    getArticleList(true)
})
homeToTopRecyclerView.setRecyclerViewLayoutManager(true)
Copy the code

Again, if it’s called from one place, it’s okay to write it, but if it’s called from many places, it’s necessary to extract it!

You can download the project and look at the historical submission, save a lot of code.

This View code

A delicate ending

Here this article is about to say goodbye to you, although the function of this article is very simple, but it can also improve some user experience! Welcome to download and experience.

Ability is general, the level is limited, to everyone helpful words don’t forget three even, have Github account to help point a Star, grateful!

That’s it, see you next time!!