How we taught the swim button

    Immediately, it’s probably worth warning that we made a floating button a little in our own way and actually before the release of the library that implements the material design as such. But first things first.

    In our concept ( applications , surfingbird.ru site), such a concept as “surf” is actively used. The service generates for the user a set of articles relevant to his interests and the transition to the next recommended article, we call "surf". After the next redesign, we lost the surf button (earlier it was on top, in the action bar, and it was not very convenient to reach it), than the users were very outraged. After watching the video with a preview of the material design, we got the idea to implement something similar in the application.

    On the one hand, we really liked the concept of a large button - which we want to press, on the other - we were very confused that the button obscured the content and seemed to be distracting or something while reading. Then our designer suggested teaching her to “swim”.

    image


    We intercept the scrolling event.

    The standard ListView component is not very eager to share detailed information about how many pixels and in which direction the user has just scrolled. In RecyclerView this is better, but ListView can be easily taught to “share”, especially since it has the necessary function. Extending the class:

    /**
     * Created by recoilme on 29.08.14.
     */
    public class ScrollDetectingListView extends ListView {
        public ScrollDetectingListView(Context context) {
            super(context);
        }
        public ScrollDetectingListView(Context context, AttributeSet attrs) {
            super(context,attrs);
        }
        public ScrollDetectingListView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
        //we need this protected method for scroll detection
        public int getVerticalScrollOffset() {
            return computeVerticalScrollOffset();
        }
    }
    


    Now, in the activity, we can determine in which direction the scroll has shifted:

            listView = (ScrollDetectingListView) aq.id(R.id.detailmain_listview).getListView();
            listView.setOnScrollListener(new AbsListView.OnScrollListener() {
                private int mInitialScroll = 0;
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
                }
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    int scrolledOffset = listView.getVerticalScrollOffset();
                    if (scrolledOffset!=mInitialScroll) {
                        //if scroll position changed
                        boolean scrollUp = (scrolledOffset - mInitialScroll) < 0;
                        mInitialScroll = scrolledOffset;
                        if (scrollUp) {
                            if (isNetworkAvailable && !animationProcess && aq.id(R.id.surfButton).getView().getVisibility() == View.GONE) {
                                actionBar.show();
                                aq.id(R.id.surfButton).animate(animFadeIn);
                            }
                        }
                        else {
                            if (isNetworkAvailable && !animationProcess && aq.id(R.id.surfButton).getView().getVisibility() == View.VISIBLE) {
                                actionBar.hide();
                                aq.id(R.id.surfButton).animate(animFadeOut);
                            }
                        }
                    }
                }
            });
    


    When the user scrolls up - the animation of the appearance of the button and the action bar starts, when down - the button is hidden. When pressed, the button is hidden, when the next surf is loaded, it appears. Everything is simple.

    Actually animations:

            isNetworkAvailable = UtilsApi.isOnline(activity);
            if (isNetworkAvailable) {
                aq.id(R.id.surfButton).visible();
            }
            else {
                aq.id(R.id.surfButton).gone();
            }
            animFadeIn = AnimationUtils.loadAnimation(getApplicationContext(),
                    R.xml.grow_from_top);
            animFadeIn.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                    animationProcess = true;
                    aq.id(R.id.surfButton).visible();
                }
                @Override
                public void onAnimationEnd(Animation animation) {
                    animationProcess = false;
                    aq.id(R.id.surfButton).visible();
                }
                @Override
                public void onAnimationRepeat(Animation animation) {}
            });
            animFadeOut = AnimationUtils.loadAnimation(getApplicationContext(),
                    R.xml.shrink_from_top);
            animFadeOut.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                    animationProcess = true;
                    aq.id(R.id.surfButton).visible();
                }
                @Override
                public void onAnimationEnd(Animation animation) {
                    animationProcess = false;
                    aq.id(R.id.surfButton).gone();
                }
                @Override
                public void onAnimationRepeat(Animation animation) {}
            });
    //grow
    
    
    //shrink
    
    


    That's all. We hope someone comes in handy. Have a nice surf!

    Also popular now: