Android背景圖下拉回彈效果實(shí)例
Android實(shí)現(xiàn)背景圖下拉回彈效果
增加設(shè)置不橫向拉伸時(shí)增加回彈效果
增加切換橫屏?xí)r可滑動(dòng)效果
效果

實(shí)現(xiàn)
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;
//zoomView原本的寬高
private int zoomViewWidth = 0;
private int zoomViewHeight = 0;
//是否正在放大
private boolean mScaling = false;
//放大的view,默認(rèn)為第一個(gè)子view
private View zoomView;
public void setZoomView(View zoomView) {
this.zoomView = zoomView;
}
//滑動(dòng)放大系數(shù),系數(shù)越大,滑動(dòng)時(shí)放大程度越大
private float mScaleRatio = 0.4f;
public void setmScaleRatio(float mScaleRatio) {
this.mScaleRatio = mScaleRatio;
}
//最大的放大倍數(shù)
private float mScaleTimes = 2f;
public void setmScaleTimes(int mScaleTimes) {
this.mScaleTimes = mScaleTimes;
}
//回彈時(shí)間系數(shù),系數(shù)越小,回彈越快
private float mReplyRatio = 0.5f;
public void setmReplyRatio(float mReplyRatio) {
this.mReplyRatio = mReplyRatio;
}
//滾動(dòng)觸發(fā)子view橫向放大的方法
private float moveDistance = 300.0f;
public void setMoveDistance(float moveDistance) {
this.moveDistance = moveDistance;
}
//是否橫向拉伸,默認(rèn)為true
private boolean isTransverse = true;
public void setTransverse(boolean isTransverse) {
this.isTransverse = isTransverse;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
//不可過度滾動(dòng),否則上移后下拉會(huì)出現(xiàn)部分空白的情況
setOverScrollMode(OVER_SCROLL_NEVER);
//獲得默認(rèn)第一個(gè)view
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:
//手指離開后恢復(fù)圖片
mScaling = false;
replyImage();
break;
case MotionEvent.ACTION_MOVE:
if (!mScaling) {
if (getScrollY() == 0) {
y = ev.getY();// 滾動(dòng)到頂部時(shí)記錄位置,否則正常返回
} else {
break;
}
}
int distance = (int) ((ev.getY() - y) * mScaleRatio); // 滾動(dòng)距離乘以一個(gè)系數(shù)
if (distance < 0) { // 當(dāng)前位置比記錄位置要小,正常返回
break;
}
// 處理放大
mScaling = true;
setZoom(distance);
return true; // 返回true表示已經(jīng)完成觸摸事件,不再處理
}
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;
}
//回彈動(dòng)畫
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="數(shù)據(jù)1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="數(shù)據(jù)2"/>
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="數(shù)據(jù)3"/>
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="數(shù)據(jù)4"/>
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="數(shù)據(jù)5"/>
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="數(shù)據(jù)6"/>
</LinearLayout>
</com.lwj.test.common.view.HeadZoomScrollView>
setZoomView(View view); // 設(shè)置要放大的view,默認(rèn)為第一個(gè)子view setmScaleRatio(float mScaleRatio); // 設(shè)置滑動(dòng)放大系數(shù),系數(shù)越大,滑動(dòng)時(shí),放大程度越大 setmScaleTimes(int mScaleTimes); // 設(shè)置最大的放大倍數(shù) setmReplyRatio(float mReplyRatio); //回彈時(shí)間系數(shù),系數(shù)越小,回彈越快 setMoveDistance(float moveDistance); // 設(shè)置放大時(shí)移動(dòng)的距離 setTransverse(boolean isTransverse); // 設(shè)置是否進(jìn)行橫向拉伸 setOnZoomListener(OnZoomListener onZoomListener);// 設(shè)置滑動(dòng)距離監(jiān)聽
總結(jié)
到此這篇關(guān)于Android背景圖下拉回彈效果實(shí)例的文章就介紹到這了,更多相關(guān)Android背景圖下拉回彈內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android 實(shí)現(xiàn)IOS選擇拍照相冊(cè)底部彈出的實(shí)例
這篇文章主要介紹了Android 實(shí)現(xiàn)IOS選擇拍照相冊(cè)底部彈出的實(shí)例的相關(guān)資料,這里提供了實(shí)現(xiàn)效果圖及實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-07-07
Android判斷網(wǎng)絡(luò)類型的方法(2g,3g還是wifi)
這篇文章主要介紹了Android判斷網(wǎng)絡(luò)類型的方法,可實(shí)現(xiàn)判斷2g,3g還是wifi的功能,結(jié)合實(shí)例形式分析了Android針對(duì)網(wǎng)絡(luò)類型的相關(guān)判定技巧,需要的朋友可以參考下2016-02-02
Android開發(fā)之拖動(dòng)條和評(píng)分組件用法分析
這篇文章主要介紹了Android開發(fā)之拖動(dòng)條和評(píng)分組件用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android拖動(dòng)條及評(píng)分組件的布局與功能實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-07-07
Android開發(fā)實(shí)現(xiàn)根據(jù)包名判斷App運(yùn)行狀態(tài)的方法
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)根據(jù)包名判斷App運(yùn)行狀態(tài)的方法,結(jié)合實(shí)例形式分析了Android結(jié)合包名判斷app運(yùn)行狀態(tài)的方法,需要的朋友可以參考下2017-11-11
Android?App應(yīng)用退到后臺(tái)顯示通知的實(shí)現(xiàn)方法
當(dāng)用戶收到app發(fā)過來的消息時(shí),如果app沒有在前臺(tái)打開,需要提醒用戶有新的消息,所以這篇文章主要給大家介紹了關(guān)于Android?App應(yīng)用退到后臺(tái)顯示通知的實(shí)現(xiàn)方法,需要的朋友可以參考下2022-01-01
android ocr——身份證識(shí)別的功能實(shí)現(xiàn)
本篇文章主要介紹了android ocr——身份證識(shí)別的功能實(shí)現(xiàn),具有一定的參考價(jià)值,有需要的可以了解一下。2016-11-11

