自定义View实现视差特效
2017-08-17 09:53
197 查看
今天我来为大家阐述一下视差特效,及回弹操作:
* 视差特效实现思路: * 1.解析OnTouche,Action_Down,Action_move,Action_up * 2.重写listview的ouverScrollyBy方法,继承式自定义控件ListView,根据用户下拉的距离,动态修改headerView的高度. * a.拷贝文本资源到项目中,自定义控件继承Listview * b.使用自定义控件,并往头部添加布局,设置适配器. * c.使用视图树,把ImageView传给我们的自定义控件 * * 实现思路以及代码里的注释我已经标记的很详细了,直接照代码撸就能实现效果 * 首先 :我们来撸 MainActivity 里的代码:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // A.View final ParallaxListView plv = (ParallaxListView) findViewById(R.id.piv); // B.ListView添加一个头布局 View headerView = View.inflate(this, R.layout.header, 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.setPrallaxImage(iv_header); // 释放资源 iv_header.getViewTreeObserver().removeGlobalOnLayoutListener(this); } }); // B.使用ListView的ArrayAdapter,添加文本的Item plv.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, Cheeses.NAMES)); } }
给Util工具类,同样借用梁山好汉109将
public class Cheeses { public static final String[] NAMES = new String[]{"宋江", "卢俊义", "吴用", "公孙胜", "关胜", "林冲", "秦明", "呼延灼", "花荣", "柴进", "李应", "朱仝", "鲁智深", "武松", "董平", "张清", "杨志", "徐宁", "索超", "戴宗", "刘唐", "李逵", "史进", "穆弘", "雷横", "李俊", "阮小二", "张横", "阮小五", "张顺", "阮小七", "杨雄", "石秀", "解珍", "解宝", "燕青", "朱武", "黄信", "孙立", "宣赞", "郝思文", "韩滔", "彭玘", "单廷珪", "魏定国", "萧让", "裴宣", "欧鹏", "邓飞", " 燕顺", "杨林", "凌振", "蒋敬", "吕方", "郭 盛", "安道全", "皇甫端", "王英", "扈三娘", "鲍旭", "樊瑞", "孔明", "孔亮", "项充", "李衮", "金大坚", "马麟", "童威", "童猛", "孟康", "侯健", "陈达", "杨春", "郑天寿", "陶宗旺", "宋清", "乐和", "龚旺", "丁得孙", "穆春", "曹正", "宋万", "杜迁", "薛永", "施恩", "周通", "李忠", "杜兴", "汤隆", "邹渊", "邹润", "朱富", "朱贵", "蔡福", "蔡庆", "李立", "李云", "焦挺", "石勇", "孙新", "顾大嫂", "张青", "孙二娘", "王定六", "郁保四", "白胜", "时迁", "段景柱", "高会全"}; }
自定义View :
/** * * author:(Administrator) * function: 继承式控件 * 1.继承listview,覆写构造方法. * 2.覆写ouverScrollyBy方法,重点的两个方法(deltaY,isTouchEvent) * 3.暴露一个方法,去得到外界的ImageView,并测量ImageView控件的高度. * 4.覆写OnTouchEvent方法 */ public class ParallaxListView extends ListView { private ImageView iv_header; private int Drawable; private int orignlHeight; public ParallaxListView(Context context) { this(context, null); } public ParallaxListView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ParallaxListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void setPrallaxImage(ImageView iv_header) { this.iv_header = iv_header; // B.获取图片的原始高度 Drawable = iv_header.getDrawable().getIntrinsicHeight(); // C.获取ImageView控件的原始高度,以便回弹时,回弹到原始高度 orignlHeight = iv_header.getHeight(); } /** * A. 滑动到ListView两端的时候才被调用 * @param deltaY 竖直方向滑动的瞬时变化量,顶部下拉为 - ; 顶部上拉为 + ; * @param scrollY * @param scrollRangeY * @param maxOverScrollY * @param isTouchEvent 是否是用户触摸拉动,true表示用户手指拉动,false是惯性 * @return */ @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("deltaY"+deltaY); System.out.println("scrollY"+scrollY); System.out.println("scrollRangeY"+scrollRangeY); System.out.println("maxOverScrollY"+maxOverScrollY); System.out.println("isTouchEvent"+isTouchEvent); // A. 顶部下拉,用户触摸的操作才执行视差效果 if(deltaY < 0 && isTouchEvent){ // A.deltaY 是负值,我们要改为绝对值,累计给我们的 iv_header 高度 int newHeight = iv_header.getHeight() + Math.abs(deltaY); /** * * 避免图片的无限放大,使图片最大不能超过图片本身的高度 * */ //B.避免图片的无限放大,是图片最大不能够超过图片本身的高度 if(newHeight <= Drawable){ //把新的高度值负值给控件,改变控件的高度 iv_header.getLayoutParams().height=newHeight; iv_header.requestLayout(); } } return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, 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, orignlHeight); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { // 获取动画执行过程中的分度值 float fraction = animator.getAnimatedFraction(); // 获取中间的值,并赋给控件新高度,可以使控件平稳回弹的效果; Integer value = (Integer) animator.getAnimatedValue(); // 让新的高度生效 iv_header.getLayoutParams().height = value; iv_header.requestLayout(); } }); // 设置动画执行时间 animator.setDuration(3000); // 动画执行 animator.start(); } return super.onTouchEvent(ev); } }
XML _ activity_main 中:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.administrator.demo.MainActivity"> <com.example.administrator.demo.ParallaxListView android:id="@+id/piv" android:layout_width="match_parent" android:layout_height="match_parent"></com.example.administrator.demo.ParallaxListView> </RelativeLayout>
相关文章推荐
- Android开发使用自定义view实现ListView下拉的视差特效功能
- Android 自定义view:实现ListView下拉的视差特效
- 仿IOS特效(一)——Android 自定义View实现3D滚轮效果的城市联动选择器
- 自定义view实战笔记--视差特效
- Android自定义控件(特效三) 自定义View实现图片验证码
- 自定义view(使用EditTetx实现记事本特效)
- 自定义View之视差特效
- 自定义View实现手机qq5.X的抽屉特效和聊天界面联系人左滑功能
- Android自定义textview实现竖直滚动跑马灯效果
- 自定义view实现未读消息提示(小红点)
- 自定义View仿TabHost的实现(二)
- Android自定义View实现比赛时间闪动效果
- 自定义ViewGroup实现ArcMenu
- 千变万化的ViewPager切换动画(2)--自定义ViewPager的实现方法
- 自定义View利用手势检测实现图片放大缩小
- android 开发第五弹---水波纹与自定义view实现绚丽粒子
- android里面自定义View实现调用activity的方法怎么做
- StackView实现自定义segment效果,且完美做到屏幕适配
- 自定义UIAlertView样式,实现可替换背景和按钮
- Android自定义View实现仿GitHub的提交活跃表格