📜 ⬆️ ⬇️

How we taught the swim button

Immediately, it is probably worth warning that we made the floating button a little bit in our own way and in fact 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 a transition to the next, recommended article we call “surf”. After another redesign, we lost the surf button (it used to be on top, in the akshenbar, and it wasn’t very comfortable to reach out to it), than the users were very indignant. After watching the video with a preview of the material design, we had the idea to implement something similar in the application.

On the one hand, we really liked the very concept of a large button - which we would like to press, on the other - we were greatly embarrassed by the fact that the button obscures the content and, as it were, distracts while reading. Then our designer offered to teach her to "swim."
')
image


We intercept the scrolling event

The standard ListView component is not very eager to share detailed information on how many pixels and in which direction the user just scrolled. In RecyclerView, this is better, but you can easily teach ListView to “share,” especially since there is a 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 activation, we can determine in which direction the scroll has dared:

  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 disappears. When pressed, the button disappears; when the next surf is loaded, it appears. It's simple.

Actually animation:

  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 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:fromXScale="0.3" android:toXScale="1.0" android:fromYScale="0.3" android:toYScale="1.0" android:pivotX="50%" android:pivotY="0%" android:duration="@android:integer/config_shortAnimTime" /> <alpha android:interpolator="@android:anim/decelerate_interpolator" android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="@android:integer/config_shortAnimTime" /> </set> //shrink <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:fromXScale="1.0" android:toXScale="0.3" android:fromYScale="1.0" android:toYScale="0.3" android:pivotX="50%" android:pivotY="100%" android:duration="@android:integer/config_shortAnimTime" /> <alpha android:interpolator="@android:anim/accelerate_interpolator" android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="@android:integer/config_shortAnimTime" /> </set> 


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

Source: https://habr.com/ru/post/245629/


All Articles