Android模仿知乎的回答详情页的动画效果

2019-12-10 19:03:34丽君

     获取了高度之后,我们就可以正确地设置位置了。但是,如果保证上面的布局随着我们的内容的移动,而改变现实状态呢?
    经过我手动直观测试,知乎的这个界面是根据一个固定的值,来改变显示状态的,因此,我们可以监听ScrollView的滑动距离,来判断。但是ScrollView并没有给我们这样一个监听器,咋办?重写!

/** 
 * Created by zhaokaiqiang on 15/2/26. 
 */ 
public class MyScrollView extends ScrollView { 
 
 private BottomListener bottomListener; 
 
 private onScrollListener scrollListener; 
 
 
 public MyScrollView(Context context) { 
  this(context, null); 
 } 
 
 public MyScrollView(Context context, AttributeSet attrs) { 
  super(context, attrs); 
 } 
 
 protected void onScrollChanged(int l, int t, int oldl, int oldt) { 
  super.onScrollChanged(l, t, oldl, oldt); 
  if (getScrollY() + getHeight() >= computeVerticalScrollRange()) { 
 
   if (null != bottomListener) { 
    bottomListener.onBottom(); 
   } 
 
  } 
 
  if (null != scrollListener) { 
   scrollListener.onScrollChanged(l, t, oldl, oldt); 
  } 
 
 
 } 
 
 public void setBottomListener(BottomListener bottomListener) { 
  this.bottomListener = bottomListener; 
 } 
 
 public void setScrollListener(onScrollListener scrollListener) { 
 
  this.scrollListener = scrollListener; 
 
 } 
 
 
 public interface onScrollListener { 
 
  public void onScrollChanged(int l, int t, int oldl, int oldt); 
 
 } 
 
 
 public interface BottomListener { 
 
  public void onBottom(); 
 
 } 
 
 
} 

    我们只需要重写onScrollChange()方法即可,在里面不光可以时时的得到位置的变化,还添加了一个BottomListener接口来监听滑动到底部的事件,写好之后就很简单了

mScroller.setBottomListener(this); 
mScroller.setScrollListener(this); 

 

/** 
  * 显示上部的布局 
  */ 
 private void showTop() { 
 
  ObjectAnimator anim1 = ObjectAnimator.ofFloat(img_bar, "y", img_bar.getY(), 
    0); 
  anim1.setDuration(TIME_ANIMATION); 
  anim1.start(); 
 
  ObjectAnimator anim2 = ObjectAnimator.ofFloat(tv_title, "y", tv_title.getY(), 
    img_bar.getHeight()); 
  anim2.setInterpolator(new DecelerateInterpolator()); 
  anim2.setDuration(TIME_ANIMATION + 200); 
  anim2.start(); 
 
  ObjectAnimator anim4 = ObjectAnimator.ofFloat(fl_top, "y", fl_top.getY(), 
    0); 
  anim4.setDuration(TIME_ANIMATION); 
  anim4.start(); 
 
  isTopHide = false; 
 } 
 
 
 /** 
  * 隐藏上部的布局 
  */ 
 private void hideTop() { 
 
  ObjectAnimator anim1 = ObjectAnimator.ofFloat(img_bar, "y", 0, 
    -img_bar.getHeight()); 
  anim1.setDuration(TIME_ANIMATION); 
  anim1.start(); 
 
  ObjectAnimator anim2 = ObjectAnimator.ofFloat(tv_title, "y", tv_title.getY(), 
    -tv_title.getHeight()); 
  anim2.setDuration(TIME_ANIMATION); 
  anim2.start(); 
 
  ObjectAnimator anim4 = ObjectAnimator.ofFloat(fl_top, "y", 0, 
    -(img_bar.getHeight() + tv_title.getHeight())); 
  anim4.setDuration(TIME_ANIMATION); 
  anim4.start(); 
 
  isTopHide = true; 
 } 
 
 @Override 
 public void onBottom() { 
  if (isToolsHide) { 
   showTools(); 
  } 
 } 
 
 @Override 
 public void onScrollChanged(int l, int t, int oldl, int oldt) { 
 
  if (t <= dp2px(TOP_DISTANCE_Y) && isTopHide && isAnimationFinish) { 
   showTop(); 
   Log.d(TAG, "显示"); 
  } else if (t > dp2px(TOP_DISTANCE_Y) && !isTopHide && isAnimationFinish) { 
   hideTop(); 
   Log.d(TAG, "隐藏"); 
  } 
 }