Android自定義ScrollView下拉圖片變大且帶有一鍵置頂功能
阿新 • • 發佈:2018-12-01
描述:下拉ScrollView時頂部的圖片隨之變大,回拉縮小,且帶有一鍵置頂的功能
1.自定義類:
import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.ScrollView; import com.iruiyou.pet.R; /** * Created by sgf * 圖片下拉放大 */ public class HeadZoomScrollView extends ScrollView implements View.OnClickListener { private ImageView goTopBtn; 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); } public void setScrollListener(ImageView goTopBtn) { this.goTopBtn = goTopBtn; this.goTopBtn.setOnClickListener(this); } // 用於記錄下拉位置 private float y = 0f; // zoomView原本的寬高 private int zoomViewWidth = 0; private int zoomViewHeight = 0; // 是否正在放大 private boolean mScaling = false; // 放大的view,預設為第一個子view 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; } @Override protected void onFinishInflate() { super.onFinishInflate(); // 不可過度滾動,否則上移後下拉會出現部分空白的情況 setOverScrollMode(OVER_SCROLL_NEVER); // 獲得預設第一個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(); } if (zoomView == null || zoomViewWidth <= 0 || zoomViewHeight <= 0) { return super.onTouchEvent(ev); } switch (ev.getAction()) { 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; case MotionEvent.ACTION_UP: mScaling = false; replyView(); break; } return super.onTouchEvent(ev); } /**放大view*/ private void setZoom(float s) { float scaleTimes = (float) ((zoomViewWidth+s)/(zoomViewWidth*1.0)); // 如超過最大放大倍數,直接返回 if (scaleTimes > mScaleTimes) return; ViewGroup.LayoutParams layoutParams = zoomView.getLayoutParams(); layoutParams.width = (int) (zoomViewWidth + s); layoutParams.height = (int)(zoomViewHeight*((zoomViewWidth+s)/zoomViewWidth)); // 設定控制元件水平居中 ((MarginLayoutParams) layoutParams).setMargins(-(layoutParams.width - zoomViewWidth) / 2, 0, 0, 0); zoomView.setLayoutParams(layoutParams); } /**回彈*/ private void replyView() { final float distance = zoomView.getMeasuredWidth() - zoomViewWidth; // 設定動畫 ValueAnimator anim = ObjectAnimator.ofFloat(distance, 0.0F).setDuration((long) (distance * mReplyRatio)); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { setZoom((Float) animation.getAnimatedValue()); } }); anim.start(); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if (onScrollListener!=null) onScrollListener.onScroll(l,t,oldl,oldt); /** * 滑動距離超過500px,出現向上按鈕,可以做為自定義屬性 */ if (t >= 500) { goTopBtn.setVisibility(View.VISIBLE); } else { goTopBtn.setVisibility(View.GONE); } } private OnScrollListener onScrollListener; public void setOnScrollListener(OnScrollListener onScrollListener) { this.onScrollListener = onScrollListener; } @Override public void onClick(View view) { if (view.getId() == R.id.im_top_course) { this.smoothScrollTo(0, 0); } } /**滑動監聽*/ public interface OnScrollListener{ void onScroll(int scrollX, int scrollY, int oldScrollX, int oldScrollY); } }
2.佈局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/_f1f1f1" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="42dp" android:orientation="vertical"> <!--<android.support.v4.widget.NestedScrollView--> <!--android:layout_width="match_parent"--> <!--android:layout_height="match_parent">--> <com.iruiyou.pet.utils.HeadZoomScrollView android:id="@+id/headzom_ScrollView" android:layout_width="match_parent" android:orientation="vertical" android:fillViewport="true" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!--標題--> <RelativeLayout android:layout_width="match_parent" android:layout_height="206dp" android:layout_alignParentBottom="true"> <ImageView android:id="@+id/im_course_bg" android:layout_width="match_parent" android:src="@drawable/background2" android:scaleType="fitXY" android:layout_height="match_parent" /> <!--<TextView--> <!--android:id="@+id/tv_course_save"--> <!--android:layout_width="wrap_content"--> <!--android:layout_height="wrap_content"--> <!--android:layout_marginTop="9dp"--> <!--android:layout_marginRight="10dp"--> <!--android:textColor="@color/white"--> <!--android:textSize="13sp"--> <!--android:layout_alignParentRight="true"--> <!--android:text="儲存" />--> <!--<TextView--> <!--android:id="@+id/tv_course_title"--> <!--android:layout_width="wrap_content"--> <!--android:layout_height="wrap_content"--> <!--android:layout_alignParentTop="true"--> <!--android:layout_centerHorizontal="true"--> <!--android:textColor="@color/white"--> <!--android:textSize="15sp"--> <!--android:layout_marginTop="9dp"--> <!--android:text="KING" />--> <!--左側返回--> <LinearLayout android:id="@+id/ll_title_course_back" android:layout_width="40dp" android:layout_height="40dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="10dp" android:layout_marginTop="9dp" android:orientation="horizontal"> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@android:color/transparent"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="@drawable/course_back" /> </RelativeLayout> </LinearLayout> </RelativeLayout> <!--課程資料--> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white" android:orientation="vertical" android:visibility="visible"> <TextView android:id="@+id/tv_course_titles" android:layout_width="match_parent" android:textColor="@color/_333333" android:layout_marginRight="22dp" android:layout_marginLeft="22dp" android:layout_marginTop="11dp" android:layout_marginBottom="11dp" android:textSize="14sp" android:text="KING" android:layout_height="wrap_content" /> <!--課程資料--> <LinearLayout android:id="@+id/ll_my_information" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:layout_marginBottom="11dp" android:layout_marginLeft="22dp" android:layout_marginRight="22dp" android:orientation="horizontal"> <ImageView android:id="@+id/im_course_head" android:layout_width="29dp" android:layout_height="29dp" android:layout_gravity="center" android:src="@drawable/head_home" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="11dp" android:orientation="vertical"> <TextView android:id="@+id/tv_course_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxLines="1" android:text="KING" android:textColor="@color/_333333" android:textSize="10sp" /> <TextView android:id="@+id/tv_course_information" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:maxLines="1" android:text="KING" android:textColor="@color/_999999" android:textSize="9sp" /> </LinearLayout> </LinearLayout> </LinearLayout> <include layout="@layout/line5"></include> <!--課程說明--> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:background="@color/white" android:gravity="center_vertical" android:orientation="horizontal"> <View android:layout_width="3dp" android:layout_height="14dp" android:layout_marginLeft="22dp" android:background="@color/_26c68a"></View> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="11dp" android:layout_weight="1" android:layout_marginRight="22dp" android:text="@string/course_description" android:textColor="@color/_666666" android:textSize="11sp" /> <!--<LinearLayout--> <!--android:layout_width="40dp"--> <!--android:layout_height="40dp"--> <!--android:gravity="center">--> <!--<ImageView--> <!--android:layout_width="wrap_content"--> <!--android:layout_height="wrap_content"--> <!--android:layout_marginRight="5dp"--> <!--android:background="@drawable/find_in"--> <!--android:textColor="@color/_999999"--> <!--android:textSize="10dp" />--> <!--</LinearLayout>--> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:orientation="vertical" android:background="@color/white" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_course_explain" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="14dp" android:layout_marginBottom="10dp" android:layout_marginLeft="22dp" android:layout_marginRight="22dp" android:text="KING" android:visibility="gone" android:textColor="@color/_666666" android:textSize="12sp" /> <com.iruiyou.pet.utils.MaxRecyclerView android:id="@+id/course_RecyclerView" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white" /> <!--<ImageView--> <!--android:id="@+id/im_course_screenshot"--> <!--android:layout_width="match_parent"--> <!--android:layout_marginRight="22dp"--> <!--android:layout_marginLeft="22dp"--> <!--android:src="@drawable/background2"--> <!--android:layout_height="134dp" />--> <TextView android:id="@+id/tv_course_introduce" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="21dp" android:layout_marginBottom="10dp" android:layout_marginLeft="22dp" android:layout_marginRight="22dp" android:visibility="gone" android:text="KING" android:textColor="@color/_666666" android:textSize="12sp" /> <include layout="@layout/line1"></include> <LinearLayout android:layout_width="match_parent" android:orientation="horizontal" android:gravity="center" android:layout_height="wrap_content"> <ImageView android:layout_width="wrap_content" android:src="@drawable/warning" android:layout_marginTop="10dp" android:layout_marginBottom="10dp" android:layout_height="wrap_content" /> <TextView android:id="@+id/tv_course_Tips" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginBottom="10dp" android:layout_marginLeft="6dp" android:textColor="@color/_333333" android:textSize="12sp" /> </LinearLayout> <include layout="@layout/line5"></include> </LinearLayout> </LinearLayout> </com.iruiyou.pet.utils.HeadZoomScrollView> <!--</android.support.v4.widget.NestedScrollView>--> </LinearLayout> <include android:id="@+id/include_foot_course" layout="@layout/include_foot_course" android:layout_width="match_parent" android:layout_height="42dp" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <ImageView android:id="@+id/im_top_course" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:visibility="gone" android:src="@drawable/im_top" android:layout_marginBottom="58dp" android:layout_marginRight="25dp"/> </RelativeLayout>
3.程式碼設定:
headzom_ScrollView.smoothScrollTo(0, 0);//預設置頂
headzom_ScrollView.setScrollListener(im_top_course);//設定一鍵置頂圖示
可以參考:一鍵置頂的ScrollView