您好,登录后才能下订单哦!
这篇文章给大家分享的是有关Android中如何使用自定义view实现ListView下拉的视差特效功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
一、概述:
现在流型的APP如微信朋友圈,QQ空间,微博个人展示都有视差特效的影子。
如图:下拉图片会产生图片拉升的效果,放手后图片有弹回到原处:

那我们如何实现呢?
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)添加到布局里:
<?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" > <com.android.imooc.paralla.ParallaListView android:id="@+id/lv_paralla" android:layout_width="match_parent" android:layout_height="match_parent" > </com.android.imooc.paralla.ParallaListView> </LinearLayout>
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<String>(ParallaActivity.this, android.R.layout.simple_list_item_1, Cheeses.NAMES));
  }
}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_header" android:scaleType="centerCrop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/parallax_img" /> </LinearLayout>
图片设成scaleType="centerCrop"模式
其它模式说明:

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中如何使用自定义view实现ListView下拉的视差特效功能”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。