实现了类似qq空间头部的图片弹性效果,手指向下滑动头部图片展示出更多部分
废话不说,上代码:
自定义的ParallaxListView:
package com.wd.demo.parallax;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
public class ParallaxListView extends ListView {
private ImageView parallaxImageView;
private int maxHeight;
private int originalHeight;
public ParallaxListView(Context context) {
this(context, null);
}
public ParallaxListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ParallaxListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* 对外提供一个传入图片的方式
*
* @param parallaxImageView
*/
public void setParallaxImageView(final ImageView parallaxImageView) {
this.parallaxImageView = parallaxImageView;
// 设置最大高度为图片的真实高度
maxHeight = parallaxImageView.getDrawable().getIntrinsicHeight();
// 利用视图树获取最初的高度
parallaxImageView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
/**
* 该方法在完成布局的时候调用
*/
@Override
public void onGlobalLayout() {
// 一般用完立即移除,因为只要有宽高变化,就会重新布局,会引起onGlobalLayout重新调用
parallaxImageView.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
originalHeight = parallaxImageView.getHeight();
}
});
}
/**
* 重新overScrollBy方法 该方法是在listview滑动到头的时候调用,并且可以在该方法中获取滑动的距离 deltaY: 继续滑动的距离
* 正值:表示底部到头 负值:顶部到头
*/
@SuppressLint("NewApi")
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
// 如果是顶部到头,并且是手指拖动到头,才让ImageView的高度增加
if (deltaY < 0 && isTouchEvent) {
// 得到ImageView的新高度
int newHeight = parallaxImageView.getHeight() - deltaY / 3;
// 对newHeight高度进行限制
if (newHeight > maxHeight)
newHeight = maxHeight;
// 将新高度设置给imageview
android.view.ViewGroup.LayoutParams params = parallaxImageView
.getLayoutParams();
params.height = newHeight;
parallaxImageView.setLayoutParams(params);
}
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY,
scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY,
isTouchEvent);
}
@SuppressLint("NewApi")
@Override
public boolean onTouchEvent(MotionEvent ev) {
// 当手指抬起的时候执行一些逻辑
if (ev.getAction() == MotionEvent.ACTION_UP) {
// 让ImageView高度缓慢恢复到初始设置的120
final ValueAnimator animator = ValueAnimator.ofInt(
parallaxImageView.getHeight(), originalHeight);
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 获取动画当前的值
int value = (Integer) animator.getAnimatedValue();
android.view.ViewGroup.LayoutParams params = parallaxImageView
.getLayoutParams();
params.height = value;
parallaxImageView.setLayoutParams(params);
}
});
animator.setInterpolator(new OvershootInterpolator());
animator.setDuration(400);
animator.start();
}
return super.onTouchEvent(ev);
}
}
ParallaxAdapter:
package com.wd.demo.parallax;
import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class ParallaxAdapter extends BaseAdapter {
private Context context;
public ParallaxAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {
return 30;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = new TextView(context);
tv.setText("哈哈哈"+position);
tv.setTextSize(30);
tv.setTextColor(Color.BLACK);
return tv;
}
}
Activity中使用:
package com.wd.demo.parallax;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ParallaxListView mPlv;
private View headerView;
private ImageView parallaxImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
/**
* 添加数据
*/
private void initData() {
mPlv.addHeaderView(headerView);
mPlv.setParallaxImageView(parallaxImageView);
mPlv.setAdapter(new ParallaxAdapter(getApplicationContext()));
}
/**
* 添加布局
*/
@SuppressLint("NewApi") private void initView() {
mPlv = (ParallaxListView) findViewById(R.id.lv);
//去掉阴影
mPlv.setOverScrollMode(AbsListView.OVER_SCROLL_NEVER);
headerView = View.inflate(getApplicationContext(), R.layout.item_header, null);
parallaxImageView = (ImageView) headerView.findViewById(R.id.iv);
}
}