需求就是让第一张的图片在拉申时跟随缩放效果。
一个可以滑动的自定义ScrollView控件,放大第一个子控件。还能监听它滑动时位置
不废话直接上效果图
这个中间放大的效果图:
直接上代码了:
自定义的ScrollView控件
/*** 自定义的下拉放大scrollView,还具备监听滑动位置的功能* 这个控件只是将它里面第一个控件放大* 只需要将第一个放ImageView控件*/public class DropEnlargeScrollView extends ScrollView implements View.OnTouchListener {// 记录首次按下位置private float mFirstPosition = 0;// 是否正在放大private Boolean mScaling = false;private View dropZoomView;private int dropZoomViewWidth;private int dropZoomViewHeight;public DropEnlargeScrollView(Context context) {super(context);}public DropEnlargeScrollView(Context context, AttributeSet attrs) {super(context, attrs);}public DropEnlargeScrollView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overrideprotected void onFinishInflate() {super.onFinishInflate();init();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);}private void init() {setOverScrollMode(OVER_SCROLL_NEVER);if (getChildAt(0) != null) {ViewGroup vg = (ViewGroup) getChildAt(0);if (vg.getChildAt(0) != null) {dropZoomView = vg.getChildAt(0);setOnTouchListener(this);}}}@Overridepublic boolean onTouch(View v, MotionEvent event) {if (dropZoomViewWidth <= 0 || dropZoomViewHeight <= 0) {dropZoomViewWidth = dropZoomView.getMeasuredWidth();dropZoomViewHeight = dropZoomView.getMeasuredHeight();}switch (event.getAction()) {case MotionEvent.ACTION_UP://手指离开后恢复图片mScaling = false;replyImage();break;case MotionEvent.ACTION_MOVE:if (!mScaling) {if (getScrollY() == 0) {mFirstPosition = event.getY();// 滚动到顶部时记录位置,否则正常返回} else {break;}}int distance = (int) ((event.getY() - mFirstPosition) * 0.6); // 滚动距离乘以一个系数if (distance < 0) { // 当前位置比记录位置要小,正常返回break;}// 处理放大mScaling = true;setZoom(distance);return true; // 返回true表示已经完成触摸事件,不再处理}return false;}// 回弹动画 (使用了属性动画)public void replyImage() {final float distance = dropZoomView.getMeasuredWidth() - dropZoomViewWidth;// 设置动画ValueAnimator anim = ObjectAnimator.ofFloat(0.0F, 1.0F).setDuration((long) (distance * 0.7));anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float cVal = (Float) animation.getAnimatedValue();setZoom(distance - ((distance) * cVal));}});anim.start();}//缩放public void setZoom(float s) {if (dropZoomViewHeight <= 0 || dropZoomViewWidth <= 0) {return;}ViewGroup.LayoutParams lp = dropZoomView.getLayoutParams();lp.width = (int) (dropZoomViewWidth + s);lp.height = (int) (dropZoomViewHeight * ((dropZoomViewWidth + s) / dropZoomViewWidth));dropZoomView.setLayoutParams(lp);}private ScrollViewListener scrollViewListener = null;/*** 需要监听滑动就在activity中,因为直接在activity中监听不了onScrollChanged事件* 如:view.setScrollViewListener(scrollViewListener)** @param scrollViewListener 滑动监听*/public void setScrollViewListener(ScrollViewListener scrollViewListener) {this.scrollViewListener = scrollViewListener;}//滑动时就触发这个方法@Overrideprotected void onScrollChanged(int x, int y, int oldx, int oldy) {super.onScrollChanged(x, y, oldx, oldy);if (scrollViewListener != null) {scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);}}}
回调接口
/*** 这个是监听滑动的回调接口*/public interface ScrollViewListener {void onScrollChanged(ScrollView scrollView, int x, int y, int oldx, int oldy);}
页面:Main2Activity
public class Main2Activity extends AppCompatActivity implements ScrollViewListener {private String TAG = "Main2Activity";private DropEnlargeScrollView de_scrollview;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main2);de_scrollview = (DropEnlargeScrollView)findViewById(R.id.de_scrollview);de_scrollview.setScrollViewListener(this);}@Overridepublic void onScrollChanged(ScrollView scrollView, int x, int y, int oldx, int oldy) {Log.d(TAG, "x = "+x+", "+"y = "+y+", "+"oldx = "+oldx+", "+"oldy = "+oldy);}}
布局页面:activity_main2.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#66666666"android:orientation="vertical"><!--注意,注意,,这个就是你存放DropEnlargeScrollView的完整路径--><com.example.administrator.test.view.DropEnlargeScrollViewandroid:id="@+id/de_scrollview"android:layout_width="match_parent"android:layout_height="wrap_content"android:scrollbars="none"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="#ffffff"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_mo_img"android:layout_width="match_parent"android:layout_height="150dp"android:layout_weight="1"android:layout_gravity="center"android:scaleType="fitXY"android:src="@mipmap/img" /><Viewandroid:layout_width="match_parent"android:layout_height="1000dp"/></LinearLayout></com.example.administrator.test.view.DropEnlargeScrollView></LinearLayout>
外话:
如果要左上顶点放大的效果图:只需要将ImageView的属性android:layout_gravity=”center”,去掉即可。