android 中scrollView顶部图片下拉放大

项目中需要在scrollView下拉的时候顶部的图片放大,网络上没有找到合适的,自己写了也


不多说了,直接上代码

这是布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ScrollView
        android:id="@+id/scollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <ImageView
                android:id="@+id/img"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:scaleType="centerCrop"
                android:src="@drawable/item" />

            <View
                android:layout_width="match_parent"
                android:layout_height="1000dp"
                android:background="#FF0000" />
        </LinearLayout>
    </ScrollView>

</LinearLayout>

注意ImageView 中的 android:layout_gravity="centerCrop"不可以少,不然放大时就不是已中点为中心放大了


Activity代码

package com.example.myscollview;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.ScrollView;

public class MainActivity extends Activity {

	private ScrollView scrollView;
	private ImageView img;

	// 记录首次按下位置
	private float mFirstPosition = 0;
	// 是否正在放大
	private Boolean mScaling = false;

	private DisplayMetrics metric;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// 获取屏幕宽高
		metric = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metric);

		//获取控件
		scrollView = (ScrollView) findViewById(R.id.scollview);
		img = (ImageView) findViewById(R.id.img);
		
		//设置图片初始大小  这里我设为满屏的16:9
		ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) img.getLayoutParams();
		lp.width = metric.widthPixels;
		lp.height = metric.widthPixels * 9 / 16;
		img.setLayoutParams(lp);
		
		//监听滚动事件
		scrollView.setOnTouchListener(new OnTouchListener() {
			@SuppressLint({ "ClickableViewAccessibility", "NewApi" })
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) img.getLayoutParams();
				switch (event.getAction()) {
				case MotionEvent.ACTION_UP:
					//手指离开后恢复图片
					mScaling = false;
					replyImage();
					break;
				case MotionEvent.ACTION_MOVE:
					if (!mScaling) {
						if (scrollView.getScrollY() == 0) {
							mFirstPosition = event.getY();// 滚动到顶部时记录位置,否则正常返回
						} else {
							break;
						}
					}
					int distance = (int) ((event.getY() - mFirstPosition) * 0.6); // 滚动距离乘以一个系数
					if (distance < 0) { // 当前位置比记录位置要小,正常返回
						break;
					}

					// 处理放大
					mScaling = true;
					lp.width = metric.widthPixels + distance;
					lp.height = (metric.widthPixels + distance) * 9 / 16;
					img.setLayoutParams(lp);
					return true; // 返回true表示已经完成触摸事件,不再处理
				}
				return false;
			}
		});

	}

	// 回弹动画 (使用了属性动画)
	@SuppressLint("NewApi")
	public void replyImage() {
		final ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) img.getLayoutParams();
		final float w = img.getLayoutParams().width;// 图片当前宽度
		final float h = img.getLayoutParams().height;// 图片当前高度
		final float newW = metric.widthPixels;// 图片原宽度
		final float newH = metric.widthPixels * 9 / 16;// 图片原高度

		// 设置动画
		ValueAnimator anim = ObjectAnimator.ofFloat(0.0F, 1.0F).setDuration(200);

		anim.addUpdateListener(new AnimatorUpdateListener() {
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				float cVal = (Float) animation.getAnimatedValue();
				lp.width = (int) (w - (w - newW) * cVal);
				lp.height = (int) (h - (h - newH) * cVal);
				img.setLayoutParams(lp);
			}
		});
		anim.start();

	}
}

大致说一下原来. 在下拉的时候,在到达顶点后,计算图片继续下拉的偏移量,对ImageView的大小进行修改,达到放大图片的效果。放手时使用属性动画,实现回弹效果。非常的简单。

不错程序有一个小bug ,先向上移动再下拉放大图片后,放手时顶部会闪出白色,如果有大神解决了这个,记得告诉我要怎么改呀。

======================2016年 1月17日==============

先向上移动再下拉放大图片后,放手时顶部会闪出白色,其实是scroll中的动画,不同的厂家会定义不同的效果。
去除的方式,在scollView中添加:
android:overScrollMode="never"

(对部分过滤了该属性的ROM无效,2.3以下的版本没有改属性)

效果图

                          


源码下载

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值