Android实现视差特效
2017-08-28 14:25
309 查看
视差特效实现思路: 1.解析OnTouche,Action_Down,Action_move,Action_up,业务逻辑过于复杂 2.重写Listview的overScrollBy方法,继承式自定义控件listview,根据用户下拉的距离,动态修改headerview的高度 a.拷贝文件资源到项目中,自定义控件继承listview b.使用自定义控件,并往头部添加布局,设置适配器 c.使用视图时,把imageview传给我们的自定义控件
main布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.demo.ParallaxLiistview android:id="@+id/plv" android:layout_width="match_parent" android:layout_height="match_parent"></com.example.demo.ParallaxLiistview> </RelativeLayout>
headerview布局(图片自行寻找)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/iv_header" android:layout_width="match_parent" android:layout_height="160dp" android:src="@drawable/t1" android:scaleType="centerCrop" /> </LinearLayout>main代码
private ParallaxLiistview plv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //A.View plv = (ParallaxLiistview) findViewById(R.id.plv); //B.listview添加一个头布局,listview的上拉加载,下拉刷新 View headerview = View.inflate(this, R.layout.headerview, null); plv.addHeaderView(headerview); final ImageView iv_header = (ImageView)headerview.findViewById(R.id.iv_header); //等view界面全部绘制完毕的时候,去得到已经绘制完控件的宽和高 iv_header.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //宽和高已经测量完毕 plv.setIv_header(iv_header); //释放资源 iv_header.getViewTreeObserver().removeGlobalOnLayoutListener(this); } }); //C.使用listview的Arrayadapter,添加文本的item plv.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,Cheeses.NAMES)); }自定义view代码
public class ParallaxLiistview extends ListView{ private ImageView iv_header; private int drawableHeight; private int orignalHeight; public ParallaxLiistview(Context context) { this(context,null); } public ParallaxLiistview(Context context, AttributeSet attrs) { this(context, attrs,0); } public ParallaxLiistview(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void setIv_header(ImageView iv_header) { this.iv_header = iv_header; //B.获取图片的原始高度 drawableHeight = iv_header.getDrawable().getIntrinsicHeight(); //c.获取imageview控件的原始高度,以便回弹时,回弹到原始高度 orignalHeight = iv_header.getHeight(); } /* A.滑动到listview两端时,才会被调用 deltaX:竖直方向滑动的瞬时变化量,顶部下拉为-,顶部上拉为+; isTouchEvent:是否是用户触摸拉动,true表示用户手指拉动,false是惯性 */ @Override protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { //A.通过Log来验证参数的作用 System.out.println("deltaX--"+deltaX+"deltaY--"+deltaY+"scrollX--"+scrollX+"scrollY--"+scrollY+"scrollRangeX--"+scrollRangeX+"scrollRangeY--"+scrollRangeY+"maxOverScrollX--"+maxOverScrollX+"maxOverScrollY--"+maxOverScrollY+"isTouchEvent--"+isTouchEvent); //A.顶部下拉,用户触摸的操作才执行视差效果 if (deltaY<0 && isTouchEvent){ //A.deltaY是负值,我们要改为绝对值,累计给我们的iv_header高度 int newHeight = iv_header.getHeight() + Math.abs(deltaY); //B.避免图片的无限放大,使图片最大不能超过图片本身的高度 if (newHeight<=drawableHeight){ //把新的高度值赋值给控件,改变控件高度 iv_header.getLayoutParams().height=newHeight; iv_header.requestLayout(); } } return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, a0b9 isTouchEvent); } //c.覆写触摸事件,让滑动图片重新恢复原有的样子 @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_UP: //把当前的头布局的高度恢复初始高度 int currentheight = iv_header.getHeight(); //属性动画,改变高度的值,把我们当前的头布局的高度改为原始高度 final ValueAnimator animator = ValueAnimator.ofInt(currentheight, orignalHeight); //动画更新的监听 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { //获取动画执行过程中的分度值 float fraction = animator.getAnimatedFraction(); //获取中间的值,并赋给控件新高度,可以使控件平稳回弹的效果 Integer animatedValue = (Integer) animator.getAnimatedValue(); //让新的高度值生效 iv_header.getLayoutParams().height=animatedValue; iv_header.requestLayout(); } }); //动画的回弹效果,值越大,回弹越厉害 animator.setInterpolator(new OvershootInterpolator(4)); //设置动画执行时间 animator.setDuration(1000); //动画执行 animator.start(); break; } return super.onTouchEvent(ev); } }
相关文章推荐
- Android通过overScrollBy实现下拉视差特效
- Android 自定义view:实现ListView下拉的视差特效
- Android开发使用自定义view实现ListView下拉的视差特效功能
- Android下Skia遮罩特效的实现
- Android 上实现水波特效
- Android游戏开发教程之十六:怎样实现图像渐变特效
- Android提高篇之TabHost结合ViewFlipper实现tab滑动翻页特效(精华版)
- Android 上实现水波特效
- android LOMO特效代码实现
- Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
- Android滑动菜单框架完全解析,教你如何一分钟实现滑动菜单特效
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(下),字母表快速滚动
- Android系统联系人全特效实现(下),字母表快速滚动
- Android特效第四篇:Android抽屉实现
- Android 上实现水波特效二--优化
- Android游戏开发之切换游戏场景特效的实现 (十九)
- android使用 2D 方法实现倒影特效
- Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
- Android 上实现水波特效二--优化