Android实现ScrollView顶部布局上滑缩小,下滑恢复

废话不多说,先上效果图:



代码实现也比较简易,我写了一个类继承了ScrollView,并重写onTouchEvent以支持头部布局的变化。

当然,这么做需要手动关联一下 头布局、图片。


上核心代码:


package com.jh.customscroll;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;

import com.jh.customscroll.exception.ParamsErrorException;

/**
 *自定义支持顶部布局上滑缩小,下滑放大的ScrollView
 */

public class MyScrollView extends ScrollView {
    private static final String TAG = "MyScrollView";

    private View headerView;
    private ImageView imgView;
    private int imgOriginalHeight;
    private int maxHeight;
    private int minHeight = 0;

    private boolean mScaling = false; // 是否正在放大
    private float downYPoint = 0;

    /**
     * 变化类型
     */
    enum ChangeType {
        /*缩小,放大*/
        Narrow, Enlarge
    }

    public MyScrollView(Context context) {
        super(context);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setHeaderView(View headerView, ImageView imgView) {
        this.headerView = headerView;
        this.imgView = imgView;
        this.imgOriginalHeight = imgView.getHeight();
        this.maxHeight = headerView.getHeight();
        if (maxHeight <= 0 || minHeight < 0 || minHeight >= maxHeight) {
            throw new ParamsErrorException("参数错误...");
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.w(TAG, "down .. Y == " + ev.getY());
                downYPoint = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE: {
                if (getScrollY() == 0) {
                    float distance = ev.getY() - downYPoint;
                    downYPoint = ev.getY();

                    if (distance < 0 && canNarrow()) {
                        measureHeaderView(distance, ChangeType.Narrow);
                        cancelPendingInputEvents();
                        return true;
                    } else if (distance > 0 && canEnlarge()) {
                        measureHeaderView(distance, ChangeType.Enlarge);
                        return true;
                    }
                }
                break;
            }
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "up .. Y == " + ev.getY());
                break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 可以缩小
     *
     * @return
     */
    private boolean canNarrow() {
        if (headerView == null) {
            return false;
        }
        return headerView.getHeight() > minHeight;
    }

    /**
     * 可以放大
     *
     * @return
     */
    private boolean canEnlarge() {
        if (headerView == null) {
            return false;
        }
        return headerView.getHeight() < maxHeight;
    }

    /**
     * 根据移动的距离,重新计算headerView的高度
     *
     * @param distance
     * @return
     */
    private void measureHeaderView(float distance, ChangeType changeType) {
        ViewGroup.LayoutParams params = headerView.getLayoutParams();
        params.height = headerView.getHeight() + (int) distance;
        if (params.height < minHeight) {
            params.height = minHeight;
        } else if (params.height > maxHeight) {
            params.height = maxHeight;
        } else if (params.height < 0) {
            params.height = 0;
        }

        Log.i(TAG, "headerView.height == " + params.height);
        headerView.setLayoutParams(params);
        measureImageView(params.height);
    }

    /**
     * 重新计算图片大小
     *
     * @param headerViewHeight
     */
    private void measureImageView(int headerViewHeight) {
        if (imgView != null) {
            double multiple = (headerViewHeight * 1.00) / (maxHeight * 1.00);
            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) imgView.getLayoutParams();
            params.height = (int) (imgOriginalHeight * multiple);
            if (params.height > imgOriginalHeight) {
                params.height = imgOriginalHeight;
            }
            imgView.setLayoutParams(params);
        }
    }

}

其余代码暂时不贴了,这里给一下资源下载地址:

CSDN:http://download.csdn.net/download/yanjunhui2011/10028253

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值