Android实现背景图下拉回弹效果
增加设置不横向拉伸时增加回弹效果 增加切换横屏时可滑动效果
效果
实现
public class HeadZoomScrollView extends NestedScrollView {
public HeadZoomScrollView ( Context context) {
super ( context) ;
}
public HeadZoomScrollView ( Context context, AttributeSet attrs) {
super ( context, attrs) ;
}
public HeadZoomScrollView ( Context context, AttributeSet attrs, int defStyleAttr) {
super ( context, attrs, defStyleAttr) ;
}
private float y = 0f ;
private int zoomViewWidth = 0 ;
private int zoomViewHeight = 0 ;
private boolean mScaling = false ;
private View zoomView;
public void setZoomView ( View zoomView) {
this . zoomView = zoomView;
}
private float mScaleRatio = 0.4f ;
public void setmScaleRatio ( float mScaleRatio) {
this . mScaleRatio = mScaleRatio;
}
private float mScaleTimes = 2f ;
public void setmScaleTimes ( int mScaleTimes) {
this . mScaleTimes = mScaleTimes;
}
private float mReplyRatio = 0.5f ;
public void setmReplyRatio ( float mReplyRatio) {
this . mReplyRatio = mReplyRatio;
}
private float moveDistance = 300.0f ;
public void setMoveDistance ( float moveDistance) {
this . moveDistance = moveDistance;
}
private boolean isTransverse = true ;
public void setTransverse ( boolean isTransverse) {
this . isTransverse = isTransverse;
}
@Override
protected void onFinishInflate ( ) {
super . onFinishInflate ( ) ;
setOverScrollMode ( OVER_SCROLL_NEVER) ;
if ( getChildAt ( 0 ) != null && getChildAt ( 0 ) instanceof ViewGroup && zoomView == null ) {
ViewGroup vg = ( ViewGroup ) getChildAt ( 0 ) ;
if ( vg. getChildCount ( ) > 0 ) {
zoomView = vg. getChildAt ( 0 ) ;
}
}
}
@Override
public boolean onTouchEvent ( MotionEvent ev) {
if ( zoomViewWidth <= 0 || zoomViewHeight <= 0 ) {
zoomViewWidth = zoomView. getMeasuredWidth ( ) ;
zoomViewHeight = zoomView. getMeasuredHeight ( ) ;
}
switch ( ev. getAction ( ) ) {
case MotionEvent . ACTION_UP:
mScaling = false ;
replyImage ( ) ;
break ;
case MotionEvent . ACTION_MOVE:
if ( ! mScaling) {
if ( getScrollY ( ) == 0 ) {
y = ev. getY ( ) ;
} else {
break ;
}
}
int distance = ( int ) ( ( ev. getY ( ) - y) * mScaleRatio) ;
if ( distance < 0 ) {
break ;
}
mScaling = true ;
setZoom ( distance) ;
return true ;
}
return super . onTouchEvent ( ev) ;
}
public void setZoom ( float zoom) {
if ( zoomViewWidth <= 0 || zoomViewHeight <= 0 ) {
return ;
}
ViewGroup. LayoutParams lp = zoomView. getLayoutParams ( ) ;
if ( isTransverse) {
if ( zoom <= moveDistance) {
lp. width = ( int ) ( zoomViewWidth) ;
} else {
lp. width = ( int ) ( zoomViewWidth + zoom) ;
if ( onZoomListener != null ) {
onZoomListener. onZoom ( zoom) ;
}
}
} else {
lp. width = ( int ) ( zoomViewWidth) ;
}
lp. height = ( int ) ( zoomViewHeight * ( ( zoomViewWidth + zoom) / zoomViewWidth) ) ;
( ( MarginLayoutParams ) lp) . setMargins ( - ( lp. width - zoomViewWidth) / 2 , 0 , 0 , 0 ) ;
zoomView. setLayoutParams ( lp) ;
}
private OnZoomListener onZoomListener;
public interface OnZoomListener {
void onZoom ( float zoom) ;
}
public void setOnZoomListener ( OnZoomListener onZoomListener) {
this . onZoomListener = onZoomListener;
}
private void replyImage ( ) {
float distance = 0f ;
if ( isTransverse) {
distance = zoomView. getMeasuredWidth ( ) - zoomViewWidth;
} else {
distance = zoomView. getMeasuredHeight ( ) - zoomViewHeight;
}
ValueAnimator valueAnimator = ValueAnimator . ofFloat ( distance, 0f ) . setDuration ( ( long ) ( distance * mReplyRatio) ) ;
valueAnimator. addUpdateListener ( new ValueAnimator. AnimatorUpdateListener ( ) {
@Override
public void onAnimationUpdate ( ValueAnimator animation) {
setZoom ( ( Float ) animation. getAnimatedValue ( ) ) ;
}
} ) ;
valueAnimator. start ( ) ;
}
}
< com.lwj.test.common.view.HeadZoomScrollView
android: id= " @+id/scroll_view"
android: layout_width= " match_parent"
android: layout_height= " match_parent" >
< LinearLayout
android: layout_width= " match_parent"
android: layout_height= " match_parent"
android: orientation= " vertical" >
< ImageView
android: id= " @+id/iv_show"
android: layout_width= " match_parent"
android: layout_height= " 200dp"
android: layout_weight= " 1"
android: src= " @drawable/ic_my_background" />
< TextView
android: layout_width= " match_parent"
android: layout_height= " 60dp"
android: text= " 数据1" />
< TextView
android: layout_width= " match_parent"
android: layout_height= " 60dp"
android: text= " 数据2" />
< TextView
android: layout_width= " match_parent"
android: layout_height= " 60dp"
android: text= " 数据3" />
< TextView
android: layout_width= " match_parent"
android: layout_height= " 60dp"
android: text= " 数据4" />
< TextView
android: layout_width= " match_parent"
android: layout_height= " 60dp"
android: text= " 数据5" />
< TextView
android: layout_width= " match_parent"
android: layout_height= " 60dp"
android: text= " 数据6" />
</ LinearLayout>
</ com.lwj.test.common.view.HeadZoomScrollView>
setZoomView ( View view) ;
setmScaleRatio ( float mScaleRatio) ;
setmScaleTimes ( int mScaleTimes) ;
setmReplyRatio ( float mReplyRatio) ;
setMoveDistance ( float moveDistance) ;
setTransverse ( boolean isTransverse) ;
setOnZoomListener ( OnZoomListener onZoomListener) ;