赞
踩
ONE Goal,ONE Passion !
我们更多地看到下拉放大,松手回弹的效果在个人中心头像布局页面使用.向下滑动的时候.头像照片会放大,松手时又会回弹回原来的大小.效果就如下:
1,当下拉时,重新设置顶部布局(一般背景为图片)的布局参数,我们只需要改变height就ok了.
2,当松开手指时,将布局参数重新设置为原来的默认值.
public class SpringListView extends ListView {
private ImageView mImageView; // 头布局image
int mOriginalHeight; //原始高度(圆图片的高度)
int mSettingHeight; //布局设置高度
float MRATIO = 3f; //手指滑动距离 X 让图像高度变大 (X / 3f).高度
public SpringListView(Context context) {
this(context, null);
}
public SpringListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SpringListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 拿到header image的高度
*
* @param view
*/
public void setHeardView(ImageView view) {
this.mImageView = view;
mSettingHeight = mImageView.getHeight();
mOriginalHeight = mImageView.getDrawable().getIntrinsicHeight();
}
/**
* @param deltaX x方向瞬间变化量 顶部下拉为 - .
* @param deltaY
* @param scrollX x方向变化量
* @param scrollY
* @param scrollRangeX x方向滑动范围
* @param scrollRangeY
* @param maxOverScrollX x方向最大滑动范围
* @param maxOverScrollY
* @param isTouchEvent 如果是手指滑动的话true,惯性滑动为false.
* @return
*/
@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) {
if (mImageView.getHeight() <= mOriginalHeight) { //头布局没有完全显示出来
int cCurrentHeight = (int) (mImageView.getHeight() + Math.abs(deltaY / MRATIO));
//改变头布局高度
mImageView.getLayoutParams().height = cCurrentHeight;
mImageView.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:
//抬起时 图片高度.
int startHeight = mImageView.getHeight();
int endHeight = mSettingHeight;
startAnim(startHeight, endHeight);
break;
}
//此次不能返回 true. 如果返回true的话,那么overScrollBy将不会执行了.因为overScrollBy
// 的调用必须经过onTouchEvent中调用的.
return super.onTouchEvent(ev);
}
/**
* 执行回弹动画
*
* @param startHeight 动画的开始位置
* @param endHeight 动画的结束位置
*/
private void startAnim(final int startHeight, final int endHeight) {
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 动画执行的的比例进度
float fraction = (float) animation.getAnimatedValue();
// 瞬间应该回弹的距离
float winkDis = (float) (fraction * (startHeight - endHeight));
//设置mImageView的高度.
mImageView.getLayoutParams().height = (int) (startHeight - winkDis);
mImageView.requestLayout();
}
});
animator.setDuration(1000);
/**
* 设置插值器
* 之所以设置不同插值器后,会有不同效果.是因为
* 插值器会改变fraction(估值器中的比例)的值.
*/
animator.setInterpolator(new BounceInterpolator());
animator.start();
}
}
public class SpringActivity extends AppCompatActivity {
private SpringListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spring);
initView();
}
private void initView() {
lv = (SpringListView) findViewById(R.id.lv);
// lv.setOverScrollMode(View.OVER_SCROLL_NEVER);
// 加Header
final View mHeaderView = View.inflate(this, R.layout.view_header, null);
final ImageView mImage = (ImageView) mHeaderView.findViewById(R.id.iv);
lv.addHeaderView(mHeaderView);
// 填充数据
lv.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, MyData.NAMES));
mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// 当布局填充结束之后, 此方法会被调用
lv.setHeardView(mImage);
mHeaderView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
}
}
头部局 : R.layout.view_header
<?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"
android:layout_width="match_parent"
android:layout_height="160dp"
android:scaleType="centerCrop"
android:src="@drawable/parallax_img" />
</LinearLayout>
页面布局 : R.layout.activity_spring
<?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"
tools:context="com.example.customview.activity.SpringActivity">
<com.example.customview.view.SpringListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.example.customview.view.SpringListView>
</RelativeLayout>
欢迎走进重温经典:
public class MyData {
public static final String[] NAMES = new String[]{"宋江", "卢俊义", "吴用",
"公孙胜", "关胜", "林冲", "秦明", "呼延灼", "花荣", "柴进", "李应", "朱仝", "鲁智深",
"武松", "董平", "张清", "杨志", "徐宁", "索超", "戴宗", "刘唐", "李逵", "史进", "穆弘",
"雷横", "李俊", "阮小二", "张横", "阮小五", " 张顺", "阮小七", "杨雄", "石秀", "解珍",
" 解宝", "燕青", "朱武", "黄信", "孙立", "宣赞", "郝思文", "韩滔", "彭玘", "单廷珪",
"魏定国", "萧让", "裴宣", "欧鹏", "邓飞", " 燕顺", "杨林", "凌振", "蒋敬", "吕方",
"郭 盛", "安道全", "皇甫端", "王英", "扈三娘", "鲍旭", "樊瑞", "孔明", "孔亮", "项充",
"李衮", "金大坚", "马麟", "童威", "童猛", "孟康", "侯健", "陈达", "杨春", "郑天寿",
"陶宗旺", "宋清", "乐和", "龚旺", "丁得孙", "穆春", "曹正", "宋万", "杜迁", "薛永", "施恩",
"周通", "李忠", "杜兴", "汤隆", "邹渊", "邹润", "朱富", "朱贵", "蔡福", "蔡庆", "李立",
"李云", "焦挺", "石勇", "孙新", "顾大嫂", "张青", "孙二娘", " 王定六", "郁保四", "白胜",
"时迁", "段景柱"};
}
ok! 下来回弹效果已经完成了.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。