0

I have view like this:

view ListView is on the whole screen and the button is always visible (on FrameLayout). I want to hide the button outside the screen (below it) with animation when user is scrolling list and he's reaching the end (animation must start before he reaches the end so it could nicely move out of the screen). How to achieve that?

EDIT

Thanks to PPartisan I created simple method onScroll which is working very well:

    public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {
        final int lastItem = firstVisibleItem + visibleItemCount;
        if(lastItem == totalItemCount & button.getVisibility() == View.VISIBLE & hideAnimStarted == false) {
            hideAnimStarted = true;
            ObjectAnimator animator = ObjectAnimator.ofFloat(button, View.TRANSLATION_Y, 100);
            animator.setDuration(300);
            animator.start();
            animator.addListener(new AnimatorListener() {                            
                @Override
                public void onAnimationStart(Animator animation) { }                            
                @Override
                public void onAnimationRepeat(Animator animation) { }                            
                @Override
                public void onAnimationEnd(Animator animation) {
                    button.setVisibility(View.GONE);    
                }                            
                @Override
                public void onAnimationCancel(Animator animation) {}
            });
        }
            else if(lastItem < totalItemCount & button.getVisibility() == View.GONE){                        
            button.setVisibility(View.VISIBLE);
            hideAnimStarted = false;                
            ObjectAnimator animator = ObjectAnimator.ofFloat(button, View.TRANSLATION_Y, 0);
            animator.setDuration(300);
            animator.start();
        }
}
user3626048
  • 706
  • 4
  • 19
  • 52

1 Answers1

0

I rarely use ListView over RecyclerView, but with RecyclerView I achieve this by implementing OnInterceptTouchEvent. ListView also has the same method that you can Override. Once you've done this, you can detect scroll events by listening for the distance between the finger down event, and the updated position once it has moved:

private static final int TOUCH_SLOP = 200; //Set this to your preference.

int originalFingerPosition;
//...

@Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        switch (e.getAction()){
            case MotionEvent.ACTION_DOWN:
                originalFingerPosition = e.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                if (e.getY() - originalFingerPos > TOUCH_SLOP){
                    //This counts as a down swipe. Do something.
                } else if (e.getY() + TOUCH_SLOP < originalFingerPosition ){
                    //This is an upswipe. Do something else.
                }
            }
        return false;
        }

Be sure to return false once you're done so you don't consume the event and prevent other views from behaving as they should with a scroll.

After that, it's just a case of launching a suitable animation, like a TranslateAnimation, to scroll the button off screen.

EDIT: If you only want the animation to occur when you reach the last item of your list, then I would instead take a look at this answer and include the code to animate the Button off screen there:

Adapted from the example given in this post

listView.setOnScrollListener(OnScrollListener);
//...
@Override
public void onScroll(AbsListView lw, final int firstVisibleItem,
             final int visibleItemCount, final int totalItemCount) {

switch(lw.getId()) {
    case android.R.id.list:
         final int lastItem = firstVisibleItem + visibleItemCount;
         if((lastItem == totalItemCount) && (button.getVisibility() == View.VISIBLE)) {
          Animation translate = new TranslateAnimation(
                    originalXPosition, originalXPosition,  originalYPosition, listView.getHeight());
            translate.setDuration(250);
            translate.setInterpolator(new LinearInterpolator());
            button.startAnimation(translate);
            button.setEnabled(false);
            button.setVisibility(View.GONE);
          } else {
          //The Opposite...
          }
     }
}
Community
  • 1
  • 1
PPartisan
  • 8,173
  • 4
  • 29
  • 48
  • Thanks, but I want to button hide only at the end of the list not any where else so how to detect reaching end of the list using onInterceptTouchEvent? – user3626048 Apr 04 '15 at 22:01
  • In that case, I'd instead look at listening for the positions of the items in the `ListView` itself. Take a look at my updated answer and the link I provided - it's untested, but how I would approach it. – PPartisan Apr 04 '15 at 22:22