-------------布局文件---------------------
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; } }