Android好用的下拉图片放大效果

我的页面下拉图片放大效果的实现

效果图如下(只不过没有动态图):
这里写图片描述

  • 首先布局分为两块,一块是有图片的上部分,另一半是下面的条目这部分
  • 自定义一个Scrollview继承于ScrollView
  • 然后onMeasure,onTouchEvent,onScrollChanged相应的方法中做处理

代码块

详细代码如下如下:

public class PullToZoomScrollView extends ScrollView {
    private  boolean isonce;//加载该View的布局时是否是第一次加载,是第一次就让其实现OnMeasure里的代码

    private LinearLayout mParentView;//布局的父布局,ScrollView内部只能有一个根ViewGroup,就是此View
    private ViewGroup mTopView;//这个是带背景的上半部分的View,下半部分的View用不到的

    private int mScreenHeight;//整个手机屏幕的高度,这是为了初始化该View时设置mTopView用的
    private int mTopViewHeight;//这个就是mTopView的高度

    private int mCurrentOffset=0;//当前右侧滚条顶点的偏移量。ScrollView右侧是有滚动条的,当下拉时,
    //滚动条向上滑,当向下滑动时,滚动条向下滑动。

    private ObjectAnimator oa;//这个是对象动画,这个在本View里很简单,也很独立,就在这里申明一下,后面有两个方法
    //两个方法是:setT(int t),reset()两个方法用到,其他都和它无关了。

    private int imageHeight ;
    private LinearLayout.LayoutParams mImageParams;
    private ImageView mImageChild;

    /**
     * 初始化获取高度值,并记录
     * @param context
     * @param attrs
     */
    public PullToZoomScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setOverScrollMode(View.OVER_SCROLL_NEVER);
        WindowManager wm= (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics metrics=new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(metrics);
        mScreenHeight=metrics.heightPixels;
        mTopViewHeight=mScreenHeight/2-(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 90, context.getResources().getDisplayMetrics());
    }

    /**
     * 将记录的值设置到控件上,并只让控件设置一次
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if(!isonce) {
            mParentView = (LinearLayout) this.getChildAt(0);
            mTopView = (ViewGroup) mParentView.getChildAt(0);
            mTopView.getLayoutParams().height = mTopViewHeight;

            //因为下拉效果会出现用户头像原地不动的情况,所以对上半部分进行测量
            //并且使用户头像也能够跟着移动
            LinearLayout linContainer = (LinearLayout) mTopView.getChildAt(1);
            RelativeLayout ReContainer = (RelativeLayout) linContainer.getChildAt(0);
            LinearLayout container = (LinearLayout) ReContainer.getChildAt(0);
            mImageChild = (ImageView) container.getChildAt(0);
            mImageParams = (LinearLayout.LayoutParams) mImageChild.getLayoutParams();
            mImageParams.setMargins(0,0,0,0);
            isonce=true;
        }
    }

    private float startY=0;//向下拉动要放大,手指向下滑时,点击的第一个点的Y坐标
    private boolean isBig;//是否正在向下拉放大上半部分View
    private boolean isTouchOne;//是否是一次连续的MOVE,默认为false,
    //在MoVe时,如果发现滑动标签位移量为0,则获取此时的Y坐标,作为起始坐标,然后置为true,为了在连续的Move中只获取一次起始坐标
    //当Up弹起时,一次触摸移动完成,将isTouchOne置为false
    private float distance=0;//向下滑动到释放的高度差
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action =ev.getAction();
        switch (action){
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                if(mCurrentOffset<=0){
                    if(!isTouchOne){
                        startY=ev.getY();
                        isTouchOne=true;
                    }
                    distance=ev.getY()-startY;
                    if(distance>0){
                        isBig=true;
                        setT((int)-distance/4);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                if(isBig) {
                    reset();
                    isBig=false;
                }
                isTouchOne=false;
            break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 对象动画要有的设置方法
     * @param t
     */
    public void setT(int t) {
        scrollTo(0, 0);
        if (t < 0) {
            mTopView.getLayoutParams().height = mTopViewHeight-t;
            mTopView.requestLayout();
            mImageParams.setMargins(0,-t,0,0);
            mImageChild.setLayoutParams(mImageParams);
        }
    }

    /**
     * 主要用于释放手指后的回弹效果
     */
    private void reset() {
        if (oa != null && oa.isRunning()) {
            return;
        }
        oa = ObjectAnimator.ofInt(this, "t", (int)-distance / 4, 0);
        oa.setDuration(150);
        oa.start();
    }

    /**
     * 这个是设置向上滑动时,上半部分View滑动速度让其小于下半部分
     * @param l
     * @param t
     * @param oldl
     * @param oldt
     */
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        mCurrentOffset = t;//右边滑动标签相对于顶端的偏移量
        //当手势上滑,则右侧滚动条下滑,下滑的高度小于TopView的高度,则让TopView的上滑速度小于DownView的上滑速度
        //DownView的上滑速度是滚动条的速度,也就是滚动的距离是右侧滚动条的距离
        //则TopView的速度要小,只需要将右侧滚动条的偏移量也就是t缩小一定倍数就行了。我这里除以2速度减小1if (t <= mTopViewHeight&&t>=0&&!isBig) {
            mTopView.setTranslationY(t / 2);//使得TopView滑动的速度小于滚轮滚动的速度
        }
        if(isBig){
            scrollTo(0,0);
        }
    }
}

(上半部分)布局文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="255dp"
    >

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@mipmap/timg"/>

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

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="45dp"
                android:gravity="center_horizontal"
                android:orientation="vertical">

                <ImageView
                    android:id="@+id/head_img"
                    android:layout_width="80dp"
                    android:layout_height="80dp"
                    android:layout_gravity="center_horizontal"
                    android:src="@mipmap/default_avatar"/>

                <TextView
                    android:id="@+id/tv_nick"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:layout_marginTop="22px"
                    android:drawablePadding="10px"
                    android:maxLength="16"
                    android:maxLines="1"
                    android:text="点我登录"
                    android:textColor="@color/white"
                    android:textSize="14sp"/>
            </LinearLayout>
        </RelativeLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:layout_marginBottom="32px"
            android:gravity="center_horizontal"
            android:orientation="horizontal">

            <LinearLayout
                android:id="@+id/ll_mine_followed"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="90px"
                android:gravity="center_horizontal"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/mine_follow"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="0"
                    android:textColor="@color/white"
                    android:textSize="14sp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:alpha="0.6"
                    android:text="我关注的"
                    android:textColor="@color/white"
                    android:textSize="24px"/>
            </LinearLayout>

            <TextView
                android:layout_width="1px"
                android:layout_height="50px"
                android:layout_marginTop="5dp"
                android:alpha="0.16"

                android:background="@color/white"/>

            <LinearLayout
                android:id="@+id/ll_follow_me"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="90px"
                android:gravity="center_horizontal"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/follow_me"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="0"
                    android:textColor="@color/white"
                    android:textSize="14sp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:alpha="0.6"
                    android:text="关注我的"
                    android:textColor="@color/white"
                    android:textSize="24px"/>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</FrameLayout>

下半部分布局就是自己定义的item了.

布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <com.guohao.myapplication.PullToZoomScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:gravity="center_horizontal">
            <include
                layout="@layout/person_center_halftop"/>
            <include
                layout="@layout/person_center_halfdown"/>
        </LinearLayout>
    </com.guohao.myapplication.PullToZoomScrollView>
</LinearLayout>

“`

郭昊个人博客


欢迎支持 http://blog.csdn.net/guohaosir.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郭_昊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值