自定义listView实现下拉放大图片,松手自动反弹效果

-------------布局文件---------------------

activity_main.xml 的布局文件如下:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.mylistview.MainActivity">

    <com.example.mylistview.HeaderListView
        android:id="@+id/lv_header"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </com.example.mylistview.HeaderListView>

</RelativeLayout>

item_layout.xml 布局如下:

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

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:text="TextView" />
</RelativeLayout>

layout_header_view.xml 布局文件:

<?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">

    <ImageView
        android:id="@+id/iv_header"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:scaleType="fitXY"
        app:srcCompat="@drawable/timg1" />
</RelativeLayout>

--------------------------------MainActivity---------------------------------------

package com.example.mylistview;

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private HeaderListView lv_header;
    private List<String> list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();//初始化数据
        initView();
    }

    private void initData() {
        list = new ArrayList<>();
        for (int i = 0; i <10 ; i++) {
            list.add(i,"数据"+i);
        }
        Toast.makeText(this, "集合中的数据是"+ list.get(2), Toast.LENGTH_SHORT).show();
    }

    private void initView() {
        lv_header = findViewById(R.id.lv_header);
        initHeaderView();// 要在 adapter 前设置
        //设置适配器
        MyAdapters myAdapter = new MyAdapters(this,list);
        lv_header.setAdapter(myAdapter);
    }
    //将头部图片添加到自定义的View中
    private void initHeaderView() {
        View headerView = getLayoutInflater().inflate(R.layout.layout_header_view,null);
        ImageView iv_header = headerView.findViewById(R.id.iv_header);//加载资源id
        lv_header.setHeaderIV(iv_header);
        lv_header.addHeaderView(headerView);
    }

}

------------------------HeaderListView---------------------------------

package com.example.mylistview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewParent;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.ImageView;
import android.widget.ListView;

/**
 * Created by John on 2018/5/31 0031.
 */

public class HeaderListView extends ListView {
    // 放大的 ImageView
    private ImageView headerIV;
    private int height;

    public void setHeaderIV(ImageView headerIV) {
        this.headerIV = headerIV;
    }

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

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

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

    /**
     * 当 view 依附到 activity 上面的时候回调
     * @param hasWindowFocus
     */
    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        if (hasWindowFocus){
            height = this.headerIV.getHeight();
        }
    }

    /**
     * 当listview 滚动到顶部的时候,还要下拉,还要网上滚动,那么这时就会调用该方法
     * @param deltaX
     * @param deltaY
     * @param scrollX
     * @param scrollY
     * @param scrollRangeX
     * @param scrollRangeY
     * @param maxOverScrollX
     * @param maxOverScrollY
     * @param isTouchEvent
     * @return
     */
    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        // 滑动过头的时候回调该方法
        // 控制 imageview 的高度逐渐增加------从而达到滚动图片放大的效果
        boolean isCollpse = resizeOverScrollBy(deltaY);

        return isCollpse == false ? isCollpse: super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }

    private boolean resizeOverScrollBy(int deltaY) {
        if (deltaY < 0){
            if (headerIV != null){
                // 当滑动到顶部的时候,还要网上滑动,就改变 imageview 的高度
                headerIV.getLayoutParams().height = headerIV.getHeight() - deltaY;
                headerIV.requestLayout();
            }
        } else {
            if (headerIV != null){
                headerIV.getLayoutParams().height = headerIV.getHeight() - deltaY;
                headerIV.requestLayout();
            }
        }
        return false;
    }
    /**
     * 当listview 没有滑动到底部或顶部时调用
     * @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);
        // 还原图片,保持imageview 的初始化高度
        // 获取imageview 的父容器(RelativeLayout)
        ViewParent parent = this.headerIV.getParent();
        if (parent != null){
            View rootView = (View)parent;
            if (rootView.getTop() < 0 && headerIV .getHeight() > height){

                headerIV.getLayoutParams().height = headerIV.getHeight() + rootView.getTop();

                // 重新摆放子控件
                rootView.layout(rootView.getLeft(), 0, rootView.getRight(), rootView.getBottom());

                // 重新绘制
                headerIV.requestLayout();
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // 监听手势抬起
        if (ev.getAction() == MotionEvent.ACTION_UP){
            MyAnimation animation = new MyAnimation(headerIV, height);
            animation.setDuration(300);
            this.headerIV.startAnimation(animation);
        }
        return super.onTouchEvent(ev);
    }

    public class MyAnimation extends Animation {

        private ImageView imageView;
        // imageview 的原始高度
        private int targetHeight;
        // 当前 imageview 的高度
        private int currentHeight;
        // 高度差 当前的减去原始的
        private int extraHeight;

        public MyAnimation(ImageView imageView, int targetHeight){
            this.imageView = imageView;
            this.targetHeight = targetHeight;
            this.currentHeight = imageView.getHeight();
            this.extraHeight = this.currentHeight - this.targetHeight;
        }

        /**
         *  当动画在不断的执行的时候回调该方法(就是监听动画执行的过程)
         * @param interpolatedTime 值得范围 0.0 到 1.0,时间变化因子
         * @param t
         */
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            super.applyTransformation(interpolatedTime, t);

            this.imageView.getLayoutParams().height = (int)(this.currentHeight
                    - extraHeight * interpolatedTime);

            this.imageView.requestLayout();
        }
    }
}

---------------------------------适配器-----------------------------------

package com.example.mylistview;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.List;

/**
 * Created by John on 2018/5/31 0031.
 */

public class MyAdapters extends BaseAdapter {
    private Context context;
    private List<String> list;

    public MyAdapters(Context context, List<String> list) {
        this.context = context;
        this.list = list;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int i) {
        return list.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder viewHolde;
        if(view == null){
            view = View.inflate(context,R.layout.item_layout,null);
            viewHolde = new ViewHolder();
            // 初始化
            viewHolde.tv_name = view.findViewById(R.id.tv_name);
            view.setTag(viewHolde);
        }else {
            viewHolde = (ViewHolder) view.getTag();
        }
        // 设置数据
        viewHolde.tv_name.setText(list.get(i));
        return view;
    }

    class ViewHolder{
        TextView tv_name;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值