Pull-down refresh like JD.com homepage

The previous article introduced the immersive status bar of the highly imitated JD.com, but compared with the header carousel on the JD.com homepage, there are still three shortcomings:
1. Above the header banner of JD.com, in addition to the suspended status bar, There is also a row of floating toolbars below the status bar, with embedded sweep icons, search boxes, and message icons;
2. Pull the entire page up, the background color of the status bar changes from transparent to dark gray, and the background color of the toolbar at the same time It also changes from transparent to white;
3. After the page is pulled down to the top, continuing to pull down will pull out a layout with the words "pull-down to refresh", and letting go at this time will trigger the page's refresh action;
the status bar and toolbar at the first point above There are corresponding solutions for the suspension effect; there are also feasible solutions for changing the background of the status bar and toolbar in the second point. On the contrary, the pull-down refresh of the third point and the pull-up monitoring of the second point are not easy to achieve.
Although Android provides a special pull-down refresh layout SwipeRefreshLayout, it does not have the effect of scrolling down the page with gestures. Some third-party open source libraries such as PullToRefresh and SmartRefreshLayout can certainly make the overall page slide down, but the drop-down layout at the top is difficult to customize, and the background color modification of the status bar and toolbar is even more irrelevant. Therefore, if you want to present the pull-down refresh effect that is completely modeled on JD.com, you can only write a custom layout control by the developer.
For a custom pull-down refresh layout, first of all, it is necessary to be able to distinguish whether the page is scrolling down normally or stretching the header to require a refresh. The difference between the two is very simple. Intuitively, it is to determine whether the current page is pulled to the top. If it has not been pulled to the top, continuing to pull down is a normal page scrolling; if it has been pulled to the top, continuing to pull down will only pull out the head prompt to refresh. So here we have to capture the event that the page is scrolled to the top, and the corresponding event is the event that the page is scrolled to the bottom. Since the home page of the App basically uses the scroll view ScrollView to implement the page scrolling function, the problem becomes how to monitor the view to scroll to the top or to the bottom. It just so happens that ScrollView provides the onScrollChanged method for changing the scrolling behavior. By overriding this method, you can determine whether it has reached the top or the bottom. The rewritten code snippet is as follows:

    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        boolean isScrolledToTop;
        boolean isScrolledToBottom;
        if (getScrollY() == 0) {
            // 下拉滚动到顶部
            isScrolledToTop = true;
            isScrolledToBottom = false;
        } else if (getScrollY() + getHeight() - getPaddingTop() - getPaddingBottom() == getChildAt(0).getHeight()) {
            // 上拉滚动到底部
            isScrolledToBottom = true;
            isScrolledToTop = false;
        } else {
            // 未拉到顶部,也未拉到底部
            isScrolledToTop = false;
            isScrolledToBottom = false;
        }
        if (mScrollListener != null) {
            if (isScrolledToTop) {
                // 触发下拉到顶部的事件
                mScrollListener.onScrolledToTop();
            } else if (isScrolledToBottom) {
                // 触发上拉到底部的事件
                mScrollListener.onScrolledToBottom();
            }
        }
    }

    private ScrollListener mScrollListener;
    // 设置滚动监听器的实例
    public void setScrollListener(ScrollListener listener) {
        mScrollListener = listener;
    }

    // 定义一个滚动监听器,用于捕捉到达顶部和到达底部的事件
    public interface ScrollListener {
        void onScrolledToBottom();
        void onScrolledToTop();
    }

After such a transformation, as long as the page Activity sets the scroll listener of the scroll view, it can judge whether the current page is pulled to the top through the onScrolledToTop method. Now that it is possible to know whether it is up or not, it is also possible to change the background color of the status bar and toolbar synchronously. The following are two renderings of the demo page pulled to the top attachment. The left picture shows the pull-up page to make it slide up as a whole. At this time, the background of the status bar becomes gray and the background of the toolbar becomes white; the right picture shows the pull-down page to make it slide up. Near the top, the backgrounds of the status bar and toolbar are back to transparent.

However, successfully monitoring whether the page reaches the top or bottom only solves the discoloration problem of the status bar and toolbar. Because the page continues to drop down when it reaches the top, what should ScrollView do? On the one hand, the entire page has been pulled to the top, causing the ScrollView to no longer be pulled; on the other hand, the drop-down header that the user sees on the JD.com homepage is actually not under the jurisdiction of the ScrollView, even if the ScrollView wants to pull the head brother. , and can only be helpless. Whether ScrollView is panicked or overwhelmed, it just shows that it is really helpless, and for this reason, a peacemaker is needed to settle the dispute between the drop-down layout and the scroll view.
This peacemaker must be the superior layout of the drop-down layout and the scroll view. Considering that the drop-down layout is on the top and the scroll view is on the bottom, it is more appropriate for the superior layout of the two to inherit the linear layout LinearLayout. The new upper-level view needs to complete the following three tasks:
1. Automatically add a pull-down refresh header at the front of the lower-level view to ensure that the drop-down header is at the top of the entire page;
2. Register scrolling for the front custom scroll view Listeners and touch listeners, where the scroll listener handles top/bottom events and the touch listener handles continuous displacement during the drop down.
3. Rewrite the onTouch function that needs to be implemented in the touch listener interface. This is the most important thing, because this function includes all the gesture drop-down tracking processing. It is necessary to accurately respond to normal pull-down gestures, and to avoid misuse of gestures that do not belong to pull-down. For example, the following situations must be taken into consideration:
1. Swipe left and right in the horizontal direction without additional processing;
2. Pull up in the vertical direction , do not do additional processing;
3. When pulling down, if it has not been pulled to the top of the page, do not do additional processing;
4. After pulling to the top and continue to pull down, while the toolbar is hidden, the pull-down head must be slid down. ;
5. Release the gesture during the pull-down refresh process, and judge the distance of the pull-down scrolling. If the distance is too short, the head will be retracted directly and the page will not be refreshed. Only when the distance is long enough, the page refresh action can be triggered, and the head will be retracted after the refresh is completed.
Now with the newly defined drop-down upper layout, with a custom scroll view, the pull-down refresh effect of the high imitation JD.com homepage can be easily achieved. The specific implementation of the home page layout template is as follows:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white">

    <!-- PullDownRefreshLayout是自定义的下拉上层布局 -->
    <com.example.event.widget.PullDownRefreshLayout
        android:id="@+id/pdrl_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- PullDownScrollView是自定义的滚动视图 -->
        <com.example.event.widget.PullDownScrollView
            android:id="@+id/pdsv_main"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <!-- 此处放具体页面的布局内容 -->
            </LinearLayout>
        </com.example.event.widget.PullDownScrollView>
    </com.example.event.widget.PullDownRefreshLayout>

    <!-- title_drag.xml是带搜索框的工具栏布局 -->
    <include layout="@layout/title_drag" />
</RelativeLayout>

The PullDownRefreshLayout and PullDownScrollView used in the above layout template, because of the large amount of code, will not be posted here. If you need it, please leave your email and I will send it separately. Run the modified test app, and the effect of pull-down refresh is shown in the following group pictures. The left picture is the screenshot when the pull-down is being pulled down, and the right picture is the screenshot when the pull-down is released and the refresh is started.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325002262&siteId=291194637