private boolean moveChallengeTo(int bottom){
  if (mChallengeView == null || !mHasLayout) {
    return false;
  }
  final int layoutBottom=getLayoutBottom();
  final int challengeHeight=mChallengeView.getHeight();
  bottom=Math.max(getMinChallengeBottom(),Math.min(bottom,getMaxChallengeBottom()));
  float offset=1.f - (float)(bottom - layoutBottom) / (challengeHeight - mChallengeBottomBound);
  mChallengeOffset=offset;
  if (offset > 0 && !mChallengeShowing) {
    setChallengeShowing(true);
  }
  mChallengeView.layout(mChallengeView.getLeft(),bottom - mChallengeView.getHeight(),mChallengeView.getRight(),bottom);
  mChallengeView.setAlpha(getChallengeAlpha());
  if (mScrollListener != null) {
    mScrollListener.onScrollPositionChanged(offset,mChallengeView.getTop());
  }
  postInvalidateOnAnimation();
  return true;
}

private boolean moveChallengeTo ( int bottom ) { if ( mChallengeView == null || ! mHasLayout ) { return false ; } final int layoutBottom = getLayoutBottom ( ) ; final int challengeHeight = mChallengeView . getHeight ( ) ; bottom = Math . max ( getMinChallengeBottom ( ) , Math . min ( bottom , getMaxChallengeBottom ( ) ) ) ; float offset = 1.f - ( float ) ( bottom - layoutBottom ) / ( challengeHeight - mChallengeBottomBound ) ; mChallengeOffset = offset ; if ( offset > 0 && ! mChallengeShowing ) { setChallengeShowing ( true ) ; } mChallengeView . layout ( mChallengeView . getLeft ( ) , bottom - mChallengeView . getHeight ( ) , mChallengeView . getRight ( ) , bottom ) ; mChallengeView . setAlpha ( getChallengeAlpha ( ) ) ; if ( mScrollListener != null ) { mScrollListener . onScrollPositionChanged ( offset , mChallengeView . getTop ( ) ) ; } postInvalidateOnAnimation ( ) ; return true ; }
move the bottom edge of mchallengeview to a new position and notify the listener if it represents a change in position . changes made through this method will be stable across layout passes . if this method is called before first layout of this slidingchallengelayout it will have no effect .
