视差特效
1.自定义listview 在里面增加HeadView
public class MylistView extends ListView {
private int drawableHeight;
private int height;
private ImageView imageview;
public MylistView(Context context) {
super(context);
}
public MylistView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MylistView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setParallaxImage(ImageView imageview) {
this.imageview = imageview;
drawableHeight = imageview.getDrawable().getIntrinsicHeight();//1464图片本身的高
height = imageview.getHeight();//480图片表现出来的高
Log.d("tag", "height: " + height + " drawableHeight: " + drawableHeight);
}
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
// deltaY : 竖直方向的瞬时偏移量 / 变化量 dx 顶部到头下拉为-, 底部到头上拉为+
// scrollY : 竖直方向的偏移量 / 变化量
// scrollRangeY : 竖直方向滑动的范围
// maxOverScrollY : 竖直方向最大滑动范围
// isTouchEvent : 是否是手指触摸滑动, true为手指, false为惯性
// 手指拉动 并且 是下拉 实现放大效果
if (isTouchEvent && deltaY < 0) {
//展示出来的高度小于图片的高度 放大到图片的高度
if (imageview.getHeight() <= drawableHeight) { //让拉三个像素,移动一个像素
int newHeight = (int) (imageview.getHeight() + Math.abs(deltaY/3.0f));
imageview.getLayoutParams().height = newHeight;
imageview.requestLayout();
}
}
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:
final int startHeight = imageview.getHeight();//获取的新的高度
final int endHeight = height;//最后展示出来的高度
//手指抬起的时候,执行动画
valueAnimator(startHeight, endHeight);
break;
default:
break;
}
return super.onTouchEvent(ev);
}
//方式一
private void valueAnimator(final int startHeight, final int endHeight) {
//动画从开始到结束,执行的监听
ValueAnimator ofInt = ValueAnimator.ofInt(1);
ofInt.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float animatedFraction = animation.getAnimatedFraction();//0--1
Integer newHeight = evaluate(animatedFraction, startHeight, endHeight);
imageview.getLayoutParams().height = newHeight;
imageview.requestLayout();
}
}); //来回插值器 张力,越大就越难拉
ofInt.setInterpolator(new OvershootInterpolator(4));
ofInt.setDuration(500);
ofInt.start();
}
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int startInt = startValue;
return (int)(startInt + fraction * (endValue - startInt));
}
}
2.MainActivity 获取listview中的孩子imageView的宽高,因为这个时候,还没有绘制完成
public class MainActivity extends Activity {
private MylistView mylistView;
private ImageView imageview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mylistView = (MylistView) findViewById(R.id.lv);
mylistView.setOverScrollMode(View.OVER_SCROLL_NEVER);//没有那个拉下来的默认特效
View inflate = View.inflate(MainActivity.this, R.layout.view_header, null);
imageview = (ImageView) inflate.findViewById(R.id.iv);
mylistView.addHeaderView(inflate);
//当加载布局完之后就会调用这个方法,就可以拿到imageview的测量高度了
mylistView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mylistView.setParallaxImage(imageview);//当布局加载完毕之后,调用这个方法,就可以得到布局中的imageview了
mylistView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
mylistView.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, Cheeses.NAMES));
}
}