Android开源:BehaviorDemo-Behavior 实现的漂亮的效果

SuzanneDeBe 7年前
   <h2>Behavior 实现的漂亮的效果</h2>    <h3>效果来源</h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/9c4911fc5036e7f21c79d79a229ea1e1.gif"></p>    <p style="text-align:center">原图</p>    <p>我的实现</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/bcefc85ff1891fea1c3c5c35611fbf1b.gif"></p>    <p style="text-align:center">c.gif</p>    <p>一些细节没有实现 ,见谅,录制的gif效果也不太好 :-(</p>    <h3>实现</h3>    <p>依赖关系</p>    <p>Tab 监听 onNestedPreScroll 来进行滑动, Toolbar 依赖 FytContent ,其余的依赖 Tab</p>    <p>变化</p>    <ul>     <li> <p>Tab 的移动是手指滑动距离的 1/2 ,会根据停下来的位置判断是应该回到原位置还是下一个状态并进行移动</p> </li>     <li> <p>VP 跟随 Tab , HeaderScrollingViewBehavior 什么的请看建议,移动则没什么难度</p> </li>     <li> <p>BGContent 跟随 Tab ,根据 Tab 运动的比例,缩放,移动,修改 里面 View 的 Alpha</p> </li>     <li> <p>BG 跟随 Tab ,首先向下移动到 BGContent 的高度的 1/2的地方</p> </li>     <li> <p>Editor 跟随 Tab ,首先移动到 BGContent 下面加上预留的 Padding ,随着比例移动并设置alpha</p> </li>     <li> <p>Icon 跟随 Tab ,根据 Tab 运动的比例进行移动和调整大小</p> </li>     <li> <p>Name 同上</p> </li>     <li> <p>Socre 同上,没有缩放</p> </li>    </ul>    <ul>     <li>ToolBarIcon 跟随 BGContent ,根据 BGContent 移动的比例修改图标的 Alpha</li>    </ul>    <p>部分代码</p>    <pre>  <code class="language-java">//TabBehavior  public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {      super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);      mUp = dy > 0;             if(isChildRequestScroll(child.getTranslationY())){//如果list需要滑动这边就不动                 consumed[1]=0;                 return;             }             consumed[1]=dy;//全部消耗             int distance = -dy / 2;//降低移动的速度                 if (child.getTranslationY() + distance < -mMaxDistance) {                 distance = -mMaxDistance;             } else if (child.getTranslationY() + distance > 0) {                 distance = 0;             } else {                 distance = (int) (child.getTranslationY() + distance);             }             child.setTranslationY(distance);  }    /**   * Child是否需要滑动   */  private boolean isChildRequestScroll(float  translationY) {    return (translationY == -mMaxDistance &&//在顶部                          mViewPager.getAdapter() != null && //有适配器                          mViewPager.getAdapter().getCount() > 0 &&//有item                          mViewPager.getAdapter() instanceof IsChildRequestScrollListener && //实现了                          ((IsChildRequestScrollListener) mViewPager.getAdapter()).requestScroll(mUp)//需要滑动                  );  }      //设置 listener 检测是否需要展开  @Override  public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {    mControlChange=true;         if(mViewPager.getAdapter() != null && //有适配器               mViewPager.getAdapter().getCount() > 0 &&//有item               mViewPager.getAdapter() instanceof SupportNeedExpendListener&&              ((SupportNeedExpendListener) mViewPager.getAdapter()).getNeedExpendListener()==null){          ((SupportNeedExpendListener) mViewPager.getAdapter()).setNeedExpendListener(this);      }       return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;  }    /**    * list fling到头的时候 展开    */   @Override   public void needExpand() {     if(!mControlChange){               mValueAnimator.setDuration(500);               mValueAnimator.removeAllUpdateListeners();               mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                   @Override                   public void onAnimationUpdate(ValueAnimator animation) {                       mTab.setTranslationY((animation.getAnimatedFraction()-1)*mMaxDistance);                   }               });               mValueAnimator.start();           }   }     /**     * 开启硬件离屏缓存,放入不服导致缓存失效的 view     * 效果都还好     */   if(mHardwareViews.size()==0){       mHardwareViews.add(parent.findViewById(R.id.txt_name));       mHardwareViews.add(parent.findViewById(R.id.img_icon));       mHardwareViews.add(parent.findViewById(R.id.lyt_score));       mHardwareViews.add(parent.findViewById(R.id.tab_layout));       mHardwareViews.add(parent.findViewById(R.id.bg));       mHardwareViews.add(parent.findViewById(R.id.lyt_editor));       mHardwareViews.add(parent.findViewById(R.id.lyt_statistics));         //开启硬件离屏缓存       mValueAnimator.addListener(new AnimatorListenerAdapter() {           @Override           public void onAnimationEnd(Animator animation) {               super.onAnimationEnd(animation);               for(View v:mHardwareViews){                   v.setLayerType(View.LAYER_TYPE_NONE,null);               }           }             @Override           public void onAnimationStart(Animator animation) {               super.onAnimationStart(animation);               for(View v:mHardwareViews){                   v.setLayerType(View.LAYER_TYPE_HARDWARE,null);               }           }       });   }</code></pre>    <p>代码是蛮简单的 ,直接看项目即可,就那几行代码, 又加了点功能 耦合度变高了的感觉欢迎 Star,提 issue 还有PR</p>    <h3>TODO</h3>    <ul>     <li>在向上fling的过程中,向下滑,会出现错乱的情况 :-(</li>    </ul>    <p> </p>    <p> </p>