Android 自定义view:实现ListView下拉的视差特效
来源:互联网 发布:sqlserver格式化工具 编辑:程序博客网 时间:2024/05/19 02:39
一、概述:
现在流型的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); }}
四、源码下载:
链接:http://pan.baidu.com/s/1sk8vzA1 密码:r33a
- Android 自定义view:实现ListView下拉的视差特效
- 自定义View实现视差特效
- 自定义View实现视差特效
- 自定义View之视差特效
- Android实现视差特效
- 自定义view实战笔记--视差特效
- 通过overScrollBy实现下拉视差特效
- 自定义View之实现ListView的下拉刷新
- android自定义view --视差动画
- 简单视差特效的实现
- Android特效-视差特效
- 自定义控件:视差特效
- 自定义视差特效
- 通过overScrollBy实现下拉视差特效(阻尼效果)
- Android自定义View之快速实现下拉刷新, 点击加载更多ListView
- android 自定义listview实现下拉刷新(一)
- android 自定义ListView实现下拉刷新
- Android自定义View实现下拉刷新控件
- java的对象类型转换
- MFC程序中如何获取控件在客户区的坐标?
- 接口实现多态
- 【Leetcode】Reverse String
- leetcode.91. Decode Ways
- Android 自定义view:实现ListView下拉的视差特效
- C++快速入门-标准输入输出
- hashCode and equals
- leetcode---Multiply Strings---大整数乘法
- java实现输出日历
- ${pageContext.request.contextPath}的作用
- Eclpise web开发时 添加web插件
- oracle instance_name db_name db_unique_name 与监听注册
- 检测是否超出int范围 && 11. Container With Most Water