欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发使用自定义view实现ListView下拉的视差特效功能

程序员文章站 2023-12-05 15:22:22
本文实例讲述了android开发使用自定义view实现listview下拉的视差特效功能。分享给大家供大家参考,具体如下: 一、概述: 现在流型的app如微信朋友圈,q...

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

一、概述:

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

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

Android开发使用自定义view实现ListView下拉的视差特效功能

那我们如何实现呢?

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"模式

其它模式说明:

Android开发使用自定义view实现ListView下拉的视差特效功能

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相关内容感兴趣的读者可查看本站专题:《android控件用法总结》、《android开发入门与进阶教程》、《android视图view技巧总结》、《android编程之activity操作技巧总结》、《android数据库操作技巧总结》及《android资源操作技巧汇总

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