android listview下拉动画效果,Android开发使用自定义view实现ListView下拉的视差特效功能...

本文实例讲述了Android开发使用自定义view实现ListView下拉的视差特效功能。分享给大家供大家参考,具体如下:

一、概述:

现在流型的APP如微信朋友圈,QQ空间,微博个人展示都有视差特效的影子。

如图:下拉图片会产生图片拉升的效果,放手后图片有弹回到原处:

af7d31c366248c31ccabcc5e1078e0e8.png

那我们如何实现呢?

1)重写ListView控件:

2)重写里面的overScrollBy方法

3)在松手后执行值动画

二、具体实现:

1.创建ParallaListView 自定义ListView

public class ParallaListView extends ListView {

private static final String TAG = "tag";

public ParallaListView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}

public ParallaListView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public ParallaListView(Context context) {

this(context, null);

}

}

2)添加到布局里:

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

android:id="@+id/lv_paralla"

android:layout_width="match_parent"

android:layout_height="match_parent" >

3)生成主页,填充数据:

public class ParallaActivity extends Activity {

private ParallaListView mListView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_paralla);

initViews();

}

private void initViews() {

mListView = (ParallaListView) findViewById(R.id.lv_paralla);

mListView.setAdapter(new ArrayAdapter(ParallaActivity.this, android.R.layout.simple_list_item_1, Cheeses.NAMES));

}

}

4)创建头布局:

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

android:id="@+id/iv_header"

android:scaleType="centerCrop"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:src="@drawable/parallax_img" />

图片设成scaleType="centerCrop"模式

其它模式说明:

6b29709d1911e1f112472abe77aa0d40.png

5)在主页里找到头布局并添加到listview里

View mHeader = LayoutInflater.from(this).inflate(R.layout.view_paralla_header, null);

mListView = (ParallaListView) findViewById(R.id.lv_paralla);

mListView.addHeaderView(mHeader);

三、功能实现:

1.现在基本能看到效果了,但我们必须要拖动图片,这就要实现这个方法overScrollBy

因为拖动是Y轴方向,所以只要打印Y轴方向的各个参数就好了

@Override

protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,

int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {

Logger.i(TAG, "deltaY="+deltaY + " scrollX="+scrollX+ " scrollRangeY="+scrollRangeY + " maxOverScrollY=" +maxOverScrollY + " isTouchEvent=" +isTouchEvent);

return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY,

isTouchEvent);

}

得到数据下拉:deltaY=-3 scrollX=0 scrollRangeY=0 maxOverScrollY=0 isTouchEvent=true

得到数据上拉:deltaY=4 scrollX=0 scrollRangeY=0 maxOverScrollY=0 isTouchEvent=true

2.如果是下拉,我们把值赋给header,但我们如何获得高度呢?

1)在主页里初始化图片,然后设置到parallaListView里

ImageView iv = (ImageView) findViewById(R.id.iv_head);

mListView.setParallaImage(iv);

2)在parallaListView创建方法setParallaImage

public void setParallaImage(ImageView iv) {

mImageView = iv;

//在这个方法里获得高度

int height = iv.getHeight();

int measureHeight = iv.getMeasuredHeight();

int instrinsicHeight = iv.getDrawable().getIntrinsicHeight();

Logger.i(TAG, "height="+height + " measureHeight="+measureHeight+ " instrinsicHeight="+instrinsicHeight );

}

得到结果:height=0 measureHeight=0 instrinsicHeight=732

为什么会如此:因为此时的图片还没有初始化

那我们如何得到高度呢?

记得有个方法叫做iv.getViewTreeObserver(),那我们就在这个方法的监听事件里得到高度

iv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

//当布局填充完成后,此方法会被调用

mListView.setParallaImage(iv);

//移除监听

iv.getViewTreeObserver().removeGlobalOnLayoutListener(this);

}

});

此时得到的高度height=240 measureHeight=240 instrinsicHeight=732

3)把值赋给图片就能实现拉伸的效果了

if (isTouchEvent && deltaY < 0) {

mHeight += Math.abs(deltaY);

if (mHeight <= mBitmapHeight) {

mImageView.getLayoutParams().height = mHeight;

mImageView.requestLayout();

}

}

3.松手后图片回弹,这个功能在onTouchEvent里实现:

@Override

public boolean onTouchEvent(MotionEvent ev) {

switch (ev.getAction()) {

case MotionEvent.ACTION_UP:

final int startHeight = mImageView.getHeight();

final int endHeight = mBitmapHeight;

//值动画

//valueAnim(startHeight, endHeight);

//竖直移动动画

ResetAnimation anim = new ResetAnimation(mImageView, startHeight, endHeight);

anim.setInterpolator(new OvershootInterpolator());

startAnimation(anim);

break;

default:

break;

}

return super.onTouchEvent(ev);

}

4、动画实现:

/**

* @描述 使用平移动画实现下拉图片后弹射回去

* @项目名称 App_imooc

* @包名 com.android.imooc.paralla

* @类名 ResetAnimation

* @author chenlin

* @date 2016年5月29日 下午12:27:00

* @version 1.0

*/

public class ResetAnimation extends Animation {

private ImageView mImageView;

private int mStartHeight;

private int mEndHeight;

public ResetAnimation(ImageView imageView, int startHeight, int endHeight) {

this.mImageView = imageView;

this.mStartHeight = startHeight;

this.mEndHeight = endHeight;

setDuration(500);

}

@Override

protected void applyTransformation(float interpolatedTime, Transformation t) {

int newHeight = (int) (ValueUtil.evalute(interpolatedTime, mStartHeight, mEndHeight) + 0.5f);

mImageView.getLayoutParams().height = newHeight;

mImageView.requestLayout();

super.applyTransformation(interpolatedTime, t);

}

}

四、源码下载:

完整实例代码点击此处本站下载。

希望本文所述对大家Android程序设计有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值