[转]Android开发:Parallax效果的ScrollerView,改编自ParallaxListView
https://github.com/nirhart/ParallaxScroll这个gethub上的地址
本文转自http://www.2cto.com/kf/201502/376970.html
最近在项目中,有用到一个仿照Path的Parallax效果,苦苦搜寻,在github上面,有一个类似的效果,不过是listview的,加一个顶部的headerView,实现了该效果,不过我需要的是ScrollerView的,于是对该代码进行的修改,实现了ScrollerView下面的Parallax效果,效果图参照如下:
在阅读下面代码前,可以先查看下Github上面的源码
我对于原先的代码进行了大量的删减,只实现了我需要的效果,看起来简单易懂,最怕那种绕来绕去的代码了,看核心的实现代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
public class ParallaxScollView extends ScrollView implements OnScrollListener { public final static double NO_ZOOM = 1 ; public final static double ZOOM_X2 = 2 ; private ImageView mImageView; private int mImageViewHeight = - 1 ; private int mDefaultImageViewHeight = 0 ; private int originImageViewHeight; private int mMaxHeight; private interface OnOverScrollByListener { public boolean overScrollBy( int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent); } private interface OnTouchEventListener { public void onTouchEvent(MotionEvent ev); } public ParallaxScollView(Context context, AttributeSet attrs, int defStyle) { super (context, attrs, defStyle); init(context); } public ParallaxScollView(Context context, AttributeSet attrs) { super (context, attrs); init(context); } public ParallaxScollView(Context context) { super (context); init(context); } public void init(Context context) { mDefaultImageViewHeight = context.getResources().getDimensionPixelSize(R.dimen.size_default_height); originImageViewHeight = context.getResources().getDimensionPixelSize(R.dimen.size_default_height); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override protected boolean overScrollBy( int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { boolean isCollapseAnimation = false ; isCollapseAnimation = scrollByListener.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent) || isCollapseAnimation; /*return isCollapseAnimation ? true : super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, 0, isTouchEvent);*/ return false ; } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } @Override protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec) { super .onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onScrollChanged( int l, int t, int oldl, int oldt) { super .onScrollChanged(l, t, oldl, oldt); View firstView = (View) mImageView.getParent(); // firstView.getTop < getPaddingTop means mImageView will be covered by top padding, // so we can layout it to make it shorter if (firstView.getTop() < getPaddingTop() && mImageView.getHeight() > mImageViewHeight) { mImageView.getLayoutParams().height = Math.max(mImageView.getHeight() - (getPaddingTop() - firstView.getTop()), mImageViewHeight); // to set the firstView.mTop to 0, // maybe use View.setTop() is more easy, but it just support from Android 3.0 (API 11) firstView.layout(firstView.getLeft(), 0 , firstView.getRight(), firstView.getHeight()); mImageView.requestLayout(); } } @Override public boolean onTouchEvent(MotionEvent ev) { touchListener.onTouchEvent(ev); return super .onTouchEvent(ev); } public void setParallaxImageView(ImageView iv) { mImageView = iv; mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP); } public void setViewsBounds( double zoomRatio) { if (mImageViewHeight == - 1 ) { mImageViewHeight = mImageView.getHeight(); if (mImageViewHeight <= 0 ) { mImageViewHeight = mDefaultImageViewHeight; } double ratio = (( double ) mImageView.getDrawable().getIntrinsicWidth()) / (( double ) mImageView.getWidth()); } } private OnOverScrollByListener scrollByListener = new OnOverScrollByListener() { @Override public boolean overScrollBy( int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { if (isTouchEvent) { if ( true ) { mImageView.getLayoutParams().height = mImageView.getHeight() - deltaY / 2 ; mImageView.requestLayout(); } } return false ; } }; private OnTouchEventListener touchListener = new OnTouchEventListener() { @Override public void onTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_UP) { if (mImageViewHeight - 1 < mImageView.getHeight()) { ResetAnimimation animation = new ResetAnimimation( mImageView, mImageViewHeight); animation.setDuration( 300 ); mImageView.startAnimation(animation); } } } }; public class ResetAnimimation extends Animation { int targetHeight; int originalHeight; int extraHeight; View mView; protected ResetAnimimation(View view, int targetHeight) { this .mView = view; this .targetHeight = targetHeight; originalHeight = view.getHeight(); extraHeight = this .originalHeight - originImageViewHeight; Log.i(debug, target heitht + targetHeight + original height + originalHeight + extraheight + extraHeight); } @Override protected void applyTransformation( float interpolatedTime, Transformation t) { int newHeight; newHeight = ( int ) (originImageViewHeight + extraHeight * ( 1 - interpolatedTime)); mView.getLayoutParams().height = newHeight; mView.requestLayout(); } } } |
第二布:在xml中,引用该ParallaxScollView:
最后一步,在activity中,引用ParallaxScrollerView,并且设置imageview:
1
2
3
|
mImageView = (ImageView) findViewById(R.id.headview); scrollView = (ParallaxScollView) findViewById(R.id.parallax_scroll_view); scrollView.setParallaxImageView(mImageView); |
大功告成,也可以在ScrollerView上实现炫酷的Parallax效果了
[转]Android开发:Parallax效果的ScrollerView,改编自ParallaxListView的更多相关文章
- 50个Android开发人员必备UI效果源码[转载]
50个Android开发人员必备UI效果源码[转载] http://blog.csdn.net/qq1059458376/article/details/8145497 Android 仿微信之主页面 ...
- Android开发——为EditText添加烟花效果的实现
)什么时候发射烟花:监听EditText的文字改变,获取文字数量的变化以确定风的方向,还有获取光标的位置确定爆炸的位置.光标的位置没有具体的方法确定坐标,要通过反射自己计算. 2. 主要实现类 库里 ...
- Android开发:文本控件详解——TextView(二)文字跑马灯效果实现
一.需要使用的属性: 1.android:ellipsize 作用:若文字过长,控制该控件如何显示. 对于同样的文字“Android开发:文本控件详解——TextView(二)文字跑马灯效果实现”,不 ...
- Android开发之去掉listview的点击效果,一行代码间接粗暴,解决你的问题。
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 Android开发之去掉listview的点击效果,一行代码间接粗暴,解决你的问题. 当你在用list ...
- [转载] 50个Android开发人员必备UI效果源码
好东西,多学习! Android 仿微信之主页面实现篇Android 仿微信之界面导航篇Android 高仿QQ 好友分组列表Android 高仿QQ 界面滑动效果Android 高仿QQ 登陆界面A ...
- Android 开发笔记___textvieww__跑马灯效果
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- Android开发实战之底部Dialog弹出效果
在Android开发中,有很多情况下我们需要使用到对话框,遗憾的是,安卓自带的对话框样式不能满足我们实际的需要,所以往往需要我们自定义对话框,具体做法:写一个对话框继承自Dialog实现他的一个构造方 ...
- Android 开发一定要看的15个实战项目
前言: 虽说网上有太多的Android课程,但是大多都是视频,有Android在线开发环境的几乎没有,但是对于学习Android的人来说拥有在线的Android开发环境是非常好的,可以随时动手操作学习 ...
- Android开发学习之路-Android中使用RxJava
RxJava的核心内容很简单,就是进行异步操作.类似于Handler和AsyncTask的功能,但是在代码结构上不同. RxJava使用了观察者模式和建造者模式中的链式调用(类似于C#的LINQ). ...
随机推荐
- JQuery easyui 笔记
1.控件启用,禁用 $form.find("input[type!='button']").removeAttr("readonly"); $form.find ...
- 初步认识html以及表格的制作
12.21,冬至,天空中还下着小雨,雾霾也没有散去,但是也没有冲散节日的气氛,心情也是倍儿好. 今天学习了不少的内容,对我来说是对之前所学的一个巩固,内容比较多也比较杂乱一些,下面以例子的形式来表现: ...
- UITextView 显示不全的问题
//设置UITextView的内边距 textView.contentInset = UIEdgeInsetsMake(0, 0, 20, 0);
- Android多线程编程之AsyncTask
进程?线程? 进程是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态的概念.每个进程都有自己的地址空间(进程空间).进程空间的大小与处理机位数有关.进程至少有5种基本状态:初始态,执行态 ...
- maven css/js 压缩配置
<plugin> <groupId>net.alchim31.maven</groupId> <art ...
- js 遇到问题
1)obj.style.attr 和obj.style[attr]区别: 2)window.onload一个页面只能出现一次: 3)border-radious实现 实心和空心圆 要点:宽度高度一样大 ...
- mac上运行appium提示错误Encountered internal error running command 解决办法
[debug] [iOS] App is not installed. Will try to install. [MJSONWP] Encountered internal error runnin ...
- 关于 Netty Channel 的 Autoread
Netty 4 的 Channel 多了一个 autoread 参数, 它的用处是在让 channel 在触发某些事件以后(例如 channelActive, channelReadComplete) ...
- spring 多线程 注入 服务层 问题
在用多线程的时候,里面要用到Spring注入服务层,或者是逻辑层的时候,一般是注入不进去的.具体原因应该是线程启动时没有用到Spring实例不池.所以注入的变量值都为null. 详细:http://h ...
- VBA使用的Randomize和DoEvents
Randomize private function getInt() dim n,m as integer Randomize n=1 m=3 getInt=Int((m+1-n)*rnd + n) ...