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();
//不可過(guò)度滾動(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:
//手指離開(kāi)后恢復(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)畫(huà)
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)聽(tīng)
總結(jié)
到此這篇關(guān)于Android背景圖下拉回彈效果實(shí)例的文章就介紹到這了,更多相關(guān)Android背景圖下拉回彈內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android實(shí)現(xiàn)九宮格抽獎(jiǎng)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)九宮格抽獎(jiǎng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
詳解Android應(yīng)用中屏幕尺寸的獲取及dp和px值的轉(zhuǎn)換
這篇文章主要介紹了Android應(yīng)用中屏幕尺寸的獲取及dp和px值的轉(zhuǎn)換方法,這里主要介紹將dp轉(zhuǎn)化為px值的例子,需要的朋友可以參考下2016-03-03
解決webview內(nèi)的iframe中的事件不可用的問(wèn)題
這篇文章主要介紹了解決webview內(nèi)的iframe中的事件不可用的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03
Android獲取本機(jī)電話(huà)號(hào)碼的簡(jiǎn)單方法
Android獲取本機(jī)電話(huà)號(hào)碼的簡(jiǎn)單方法,需要的朋友可以參考一下2013-05-05
Android?studio開(kāi)發(fā)實(shí)現(xiàn)計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了Android?studio開(kāi)發(fā)實(shí)現(xiàn)計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
Android開(kāi)發(fā)筆記之:對(duì)實(shí)踐TDD的一些建議說(shuō)明
本篇文章是對(duì)Android中實(shí)踐TDD的一些建議進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Android5.0多種側(cè)滑欄效果實(shí)例代碼
這篇文章主要介紹了Android5.0多種側(cè)滑欄效果實(shí)例代碼的相關(guān)資料,本文圖文并茂介紹的非常詳細(xì),需要的朋友可以參考下2016-09-09
Android端使用Modbus協(xié)議的簡(jiǎn)單方法
Modbus協(xié)議是全球第一個(gè)用于工業(yè)現(xiàn)場(chǎng)的總線(xiàn)協(xié)議,與外設(shè)交互可以采用串口通信,tcp等方式,這篇文章主要給大家介紹了關(guān)于Android端使用Modbus協(xié)議的簡(jiǎn)單方法,需要的朋友可以參考下2021-11-11
Android自定義ViewGroup實(shí)現(xiàn)標(biāo)簽流容器FlowLayout
這篇文章主要介紹了Android自定義ViewGroup實(shí)現(xiàn)FlowLayout標(biāo)簽流容器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09

