Animate/hide 接近 ListView 末尾时的按钮

Animate/hide button when close to end of ListView

我有这样的看法:

ListView 在整个屏幕上,按钮始终可见(在 FrameLayout 上)。当用户滚动列表并且他到达终点时,我想用动画将按钮隐藏在屏幕外(在它下面)(动画必须在他到达终点之前开始,以便它可以很好地移出屏幕)。如何实现?

编辑

感谢 PPartisan 我创建了简单的 onScroll 方法,它运行良好:

    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();
        }
}

我很少使用 ListView 而不是 RecyclerView,但是使用 RecyclerView 我通过实施 OnInterceptTouchEvent 来实现这一点。 ListView 也有 the same method 可以覆盖。完成此操作后,您可以通过侦听手指按下事件与移动后更新位置之间的距离来检测滚动事件:

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;
        }

完成后请务必 return false,这样您就不会使用该事件并防止其他视图按照它们应有的滚动方式运行。

之后,只需启动合适的动画,例如 TranslateAnimation,即可将按钮滚动到屏幕外。

编辑: 如果您只希望动画在您到达列表的最后一项时出现,那么我会看一下 this 答案并包含代码以使 Button 在屏幕外动画化:

改编自 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...
          }
     }
}