自定义ListView

来源:互联网 发布:vue.js开发app实例 编辑:程序博客网 时间:2024/05/20 14:24

自定义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;        }    }}