思路:主要是listview有个OverScrollBy()方法,它是listview滑动到头部时候还能滑动,先获取imageview的最初高度,然后再滑动的过程中动态去计算imageview的高度,直到imageview显示图片的原始高度
package com.example.adminis.lsitview; import android.annotation.TargetApi; import android.app.Activity; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewTreeObserver; import android.widget.AbsListView; import android.widget.ImageView; import com.custom.widget.CustomListView; import com.example.adminis.lsitview.adapter.MyAdapter; import java.util.ArrayList; import java.util.List; public class MainActivity extends Activity { private CustomListView custom_listview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); custom_listview = (CustomListView) findViewById(R.id.custom_listview); final View heaerView = LayoutInflater.from(this).inflate(R.layout.header_lv,null); final ImageView iv_header_view = (ImageView) heaerView.findViewById(R.id.iv_header_view); custom_listview.addHeaderView(heaerView); MyAdapter adapter = new MyAdapter(initData(),this); custom_listview.setAdapter(adapter); heaerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public void onGlobalLayout() { custom_listview.setView(iv_header_view); heaerView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); } private List<String> initData() { List<String> datas = new ArrayList<String>(); for(int i=0;i<20;i++){ datas.add("求你拉我吧,我要反弹---"); } return datas; } }
自定义listviewCustomListView
package com.custom.widget; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.HeaderViewListAdapter; import android.widget.ImageView; import android.widget.ListAdapter; import android.widget.ListView; import com.com.custom.animation.ResetHeightAnimation; /** * Created by Adminis on 2016/1/29. */ public class CustomListView extends ListView { private static final String TAG = "CustomListView"; private ImageView iv_header_view; private int maxImgHeight;//图片的最大高度 private int originalHeight;//imageview 图片对应的原始高度 public CustomListView(Context context) { super(context); } public CustomListView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } /** * 当listview滑动到头的时候被调用 * Add a fixed view to appear at the top of the list. If addHeaderView is * called more than once, the views will appear in the order they were * added. Views added using this call can take focus if they want. * <p> * Note: When first introduced, this method could only be called before * setting the adapter with {@link #setAdapter(ListAdapter)}. Starting with * {@link android.os.Build.VERSION_CODES#KITKAT}, this method may be * called at any time. If the ListView's adapter does not extend * {@link HeaderViewListAdapter}, it will be wrapped with a supporting * @param deltaX Change in X in pixels * @param deltaY Change in Y in pixels * @param scrollX Current X scroll value in pixels before applying deltaX * @param scrollY Current Y scroll value in pixels before applying deltaY * @param scrollRangeX Maximum content scroll range along the X axis * @param scrollRangeY Maximum content scroll range along the Y axis * @param maxOverScrollX Number of pixels to overscroll by in either direction * along the X axis. * @param maxOverScrollY Number of pixels to overscroll by in either direction * along the Y axis. 滑动到头部最多还可以滑动多少 * @param isTouchEvent true if this scroll operation is the result of a touch event. * @return true if scrolling was clamped to an over-scroll boundary along either * axis, false otherwise. isTouch true就是手慢慢的滑动到头部 false表示一瞬间滑动到头部有惯性的 */ @Override protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { if(deltaY<0&&isTouchEvent){ //当前的高度+拖动的距离 动态改变imageview的高度 int resetHeight = iv_header_view.getHeight()-deltaY; if(resetHeight>maxImgHeight){ resetHeight = maxImgHeight; } iv_header_view.getLayoutParams().height = resetHeight; iv_header_view.requestLayout();//重新 layout --->onLayout去动态计算他的高度 } return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_UP: ResetHeightAnimation resetHeightAnimation = new ResetHeightAnimation(iv_header_view,originalHeight); startAnimation(resetHeightAnimation); break; } return super.onTouchEvent(ev); } public void setView(ImageView view) { this.iv_header_view = view; this.originalHeight = view.getHeight(); maxImgHeight = iv_header_view.getDrawable().getIntrinsicHeight(); } }
ResetHeightAnimation是一个模拟动画在一定时间改变属性
package com.com.custom.animation; import android.view.View; import android.view.animation.Animation; import android.view.animation.OvershootInterpolator; import android.view.animation.Transformation; /** * Created by Adminis on 2016/1/29. */ public class ResetHeightAnimation extends Animation { private View view; private int targetHeight; private int originalHeight;//imageview最初的高度 private int totalHeight; public ResetHeightAnimation(View view,int targetHeight) { this.view = view; this.targetHeight = targetHeight; originalHeight = view.getHeight(); totalHeight = targetHeight-originalHeight; setDuration(400); setInterpolator(new OvershootInterpolator()); } /** * * @param interpolatedTime 动画执行的进度 默认是0--1 或者百分比 比如他是0.5表示动画执行了50% * @param t */ @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); int resetHeight = (int) (originalHeight+totalHeight*interpolatedTime); view.getLayoutParams().height = resetHeight; view.requestLayout(); } }
图:
xml文件就不必贴了,到此为止 该休息了