1.定义一个类继承ListView
主要用到的是越界滚动 overScrollBy()
onTouchEvent() 中松开手后自动回滚到原来的高度,用到了属性动画和插补器
public class ParallaxEffectView extends ListView {
private ImageView imageView;
private int intrinsicHeight;
private int originalHeight;
private ValueAnimator va;
public ParallaxEffectView(Context context) {
this(context, null);
}
public ParallaxEffectView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ParallaxEffectView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
}
//重写方法overScrollBy
/**
* 超过边界滚动
*
* @param deltaX
* @param deltaY 系统每隔一段时间,检测手指移动的距离
* @param scrollX
* @param scrollY 视图滚动的距离
* @param scrollRangeX
* @param scrollRangeY 滚动的y的范围
* @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) {
Log.i("test", "deltaY:" + deltaY + ",scrollY:" + scrollY + ", scrollRangeY:" + scrollRangeY + ", maxOverScrollY:" + maxOverScrollY + ", isTouchEvent:" + isTouchEvent);
if (isTouchEvent) {//是否越过边界滚动
//向下拉
if (deltaY < 0) {//系统每隔一段时间,检测手指移动的距离
//让图片的高度增加
int oldHeight = imageView.getLayoutParams().height;
int newHeight = oldHeight + Math.abs(deltaY);
if (newHeight > intrinsicHeight * 0.5f) {
newHeight = (int) (intrinsicHeight * 0.5f);
}
imageView.getLayoutParams().height = newHeight;
//让更改后的布局参数生效
imageView.requestLayout();
}
}
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}
public void setImageView(ImageView imageView) {
this.imageView = imageView;
//获取图片源的真实高度
intrinsicHeight = imageView.getDrawable().getIntrinsicHeight();
Log.i("test", "intrinsicHeight:" + intrinsicHeight);
//获取ImageView最初的高度
originalHeight = imageView.getLayoutParams().height;//就是在布局中设置的高度
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
//在down的时候,如果动画在执行,取消动画
if(va!=null){
if(va.isRunning()){
va.cancel();
}
}
break;
case MotionEvent.ACTION_UP:
va = ValueAnimator.ofInt(imageView.getLayoutParams().height,originalHeight);//从现在的高度减小到原始的高度
//添加动画改变的监听
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//实时获取变化的高度,设置到ImageView上,刷新
int height = (int) animation.getAnimatedValue();
imageView.getLayoutParams().height=height;
imageView.requestLayout();;
}
});
//动画执行到终点,超过执行一段距离再回调终点
va.setInterpolator(new OvershootInterpolator(5));
va.setDuration(300);
va.start();
break;
}
return super.onTouchEvent(ev);
}
}
2.布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.itheima.parallaxeffecthm91.ParallaxEffectView
android:id="@+id/pev"
android:layout_width="match_parent"
android:layout_height="match_parent"></com.itheima.parallaxeffecthm91.ParallaxEffectView>
</RelativeLayout>
3.activity
给ListView添加头条目并通过适配器展示数据
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,Cheeses.NAMES);
ParallaxEffectView pev= (ParallaxEffectView) findViewById(R.id.pev);
//图片
View view = View.inflate(this, R.layout.header, null);
ImageView iv_head= (ImageView) view.findViewById(R.id.iv_head);
pev.setImageView(iv_head);
//将图片视图添加到头条目
pev.addHeaderView(view);
pev.setAdapter(adapter);
}
}
4.图片布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/iv_head"
android:layout_width="match_parent"
android:layout_height="160dp"
android:scaleType="centerCrop"
android:src="@drawable/parallax_img" />
</LinearLayout>