自定义ListView

自定义ListView继承控件实现下拉放大图片,松手自动反弹效果

activity_main文件布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="dongzhou.bwie.com.dongzhou20171121.MainActivity">
    <!--android:cacheColorHint="@android:color/transparent" 滚动ListView时不会掉黑 。
       滚动时,重绘View的时候就不会有背景颜色。-->
xx是自己的包名
    <xx.HeaderListView
        android:id="@+id/lv_header"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="@android:color/transparent">

    </xx.HeaderListView>
</RelativeLayout>
layout_heared_view.xml布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="150dp">
    <!-- android:scaleType="centerCrop"设置该属性 imageview 才可以缩放-->
    <ImageView
        android:id="@+id/iv_header"
        android:layout_width="match_parent"
        android:layout_height="180dp"
        android:scaleType="centerCrop"
        android:src="@mipmap/ic_launcher"/>
</RelativeLayout>
item_layout.xml文件布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:gravity="center_horizontal"
    android:paddingLeft="10dp"
    android:paddingRight="10dp">
    <ImageView
        android:id="@+id/iv"
        android:layout_width="65dp"
        android:layout_height="65dp"
        android:scaleType="fitXY"
        android:src="@mipmap/ic_launcher"/>

    <!--TextView 中的内容只是为了演示效果,真正显示的内容在枚举中-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="10dp">

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="梦想"
            android:textSize="16sp"/>

        <TextView
            android:id="@+id/tv_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="爱好学习,努力奋斗,玩玩游戏,喜欢优雅的环境,上进心强"
            android:textSize="14sp"/>

    </LinearLayout>
</LinearLayout>
在HeaderListView中要继承ListView
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();
        }
    }

}

在MainActivity中
public class MainActivity extends AppCompatActivity {
    // 定义显示的数据
    public enum Data{
        item_1("Crazy", "学习Android的学员", R.mipmap.ic_launcher),
        item_2("Crazy", "学习Android的学员", R.mipmap.ic_launcher),
        item_3("Crazy", "学习Android的学员", R.mipmap.ic_launcher),
        item_4("Crazy", "学习Android的学员", R.mipmap.ic_launcher),
        item_5("Crazy", "学习Android的学员", R.mipmap.ic_launcher),
        item_6("Crazy", "学习Android的学员", R.mipmap.ic_launcher),
        item_7("Crazy", "学习Android的学员", R.mipmap.ic_launcher),
        item_8("Crazy", "学习Android的学员", R.mipmap.ic_launcher),
        item_9("Crazy", "学习Android的学员", R.mipmap.ic_launcher),
        item_10("Crazy", "学习Android的学员", R.mipmap.ic_launcher),
        item_11("Crazy", "学习Android的学员", R.mipmap.ic_launcher),
        item_12("Crazy", "学习Android的学员", R.mipmap.ic_launcher);


        private String name;
        private String content;
        private int resId;

        private Data(String name, String content, int resId) {
            this.name = name;
            this.content = content;
            this.resId = resId;
        }

        public String getName() {
            return name;
        }

        public int getResId() {
            return resId;
        }

        public String getContent() {
            return content;
        }
    }

    private HeaderListView lv_header;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
这里要注意顺序不能写反
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        initView();
    }

    private void initView() {
        lv_header = (HeaderListView) findViewById(R.id.lv_header);
        initHeaderView();// 要在 adapter 前设置
        MyAdapter myAdapter = new MyAdapter(this);
        lv_header.setAdapter(myAdapter);
    }

    private void initHeaderView() {
        View headerView = getLayoutInflater().inflate(R.layout.layout_header_view, null);
        ImageView iv_header = (ImageView)headerView.findViewById(R.id.iv_header); // 传入
        lv_header.setHeaderIV(iv_header);
        lv_header.addHeaderView(headerView);
    }
    public class MyAdapter extends BaseAdapter {

        public MyAdapter(Context context){

        }

        @Override
        public int getCount() {
            return Data.values().length;
        }

        @Override
        public Object getItem(int position) {
            return Data.values()[position];
        }

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            ViewHolder viewHolder = null;
            if (convertView == null){
                convertView = getLayoutInflater().inflate(R.layout.item_layout, parent, false);
                viewHolder = new ViewHolder();
                // 初始化
                viewHolder.iv = (ImageView)convertView.findViewById(R.id.iv);
                viewHolder.tv_name = (TextView)convertView.findViewById(R.id.tv_name);
                viewHolder.tv_content = (TextView)convertView.findViewById(R.id.tv_content);

                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder)convertView.getTag();
            }
            // 设置数据
            Data data = Data.values()[position];
            viewHolder.iv.setImageResource(data.resId);
            viewHolder.tv_name.setText(data.getName());
            viewHolder.tv_content.setText(data.getContent());
            return convertView;
        }

        class ViewHolder{
            ImageView iv;
            TextView tv_name;
            TextView tv_content;
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值