本来项目是用的viewpager实现的轮播滚动,但是客户觉得轮播的效果太大众化了,于是就要我们改成渐变切换的效果。听到这需求,我最先想到是给viewpager设置切换动画,但是无论怎么设置动画,都要手动切换的时候才有效果。于是我就自定义了一个控件,利用淡入淡出动画实现了这效果,还是先上效果图,没效果图说再多也没用。
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
public class Gradient extends RelativeLayout { private List<ImageView> imageViews; private List<Animation> outAnim; //淡出动画 private List<Animation> inAnim; //淡入动画 private Context mContext; private Handler handler = new Handler(Looper.getMainLooper()); private int couot; private int currentIndex; //当前的页面 private LinearLayout linearLayout; private onClickListner listner; private long time= 3000 ; //动画间隔时间 public Gradient(Context context) { this (context, null ); } public Gradient(Context context, AttributeSet attrs) { super (context, attrs); this .mContext = context; } /** * 画点 */ public void cratePoint() { if ( null != imageViews && imageViews.size() > 0 ) { int size = imageViews.size(); linearLayout = new LinearLayout(mContext); linearLayout.setOrientation(LinearLayout.HORIZONTAL); linearLayout.setGravity(Gravity.CENTER); // 添加图片 for ( int i = 0 ; i < size; i++) { // 设置圆点 View viewPoint = new View(mContext); viewPoint.setBackgroundResource(R.drawable.point_background); int weight = dip2px(mContext, 5 ); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(weight, weight); lp.leftMargin = weight; viewPoint.setLayoutParams(lp); viewPoint.setEnabled( false ); linearLayout.addView(viewPoint); } View childAt = linearLayout.getChildAt( 0 ); if ( null != childAt) { childAt.setEnabled( true ); } //添加到图片的下边 RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(- 1 ,- 2 ); rlp.bottomMargin = dip2px(mContext, 5 ); rlp.addRule(ALIGN_PARENT_BOTTOM); this .addView(linearLayout, rlp); } } /** * 根据手机的分辨率从 dip 的单位 转成为 px(像素) */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return ( int ) (dpValue * scale + 0 .5f); } /** * 设置图片 * @param imageViews */ public void setImageViews(List<ImageView> imageViews) { this .imageViews = imageViews; for ( int i = 0 ; i < imageViews.size(); i++) { RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(- 1 ,- 1 ); addView(imageViews.get(i),layoutParams); } setonClick(); cratePoint(); createAnim(); start(); } /** * 开启动画 */ private void start() { final int size = imageViews.size(); handler.post( new Runnable() { @Override public void run() { final int i = couot % size; //解决点击事件的冲突 for ( int j = 0 ; j < size; j++) { if (j == i) { imageViews.get(i).setClickable( true ); } else { imageViews.get(i).setClickable( false ); } } if (couot < size) { if (i == size - 1 ) { ImageView imageView = imageViews.get( 0 ); imageView.startAnimation(outAnim.get( 0 )); ImageView imageView2 = imageViews.get(size - 1 ); imageView2.startAnimation(inAnim.get(size - 1 )); } else { //当前的淡出,下一张淡入 ImageView imageView = imageViews.get(size - 1 - i); imageView.startAnimation(outAnim.get(size - 1 - i)); } } else { if (i == size - 1 ) { //当显示到最后一张的时候,要跳到第一张 ImageView imageView = imageViews.get( 0 ); imageView.startAnimation(outAnim.get( 0 )); ImageView imageView2 = imageViews.get(size - 1 ); imageView2.startAnimation(inAnim.get(size - 1 )); } else { //当前的淡出,下一张淡入 ImageView imageView = imageViews.get(size - 1 - i); imageView.startAnimation(outAnim.get(size - 1 - i)); ImageView imageView2 = imageViews.get(size - 2 - i); imageView2.startAnimation(inAnim.get(size - 2 - i)); } } currentIndex = i; linearLayout.getChildAt(currentIndex % size).setEnabled( false ); currentIndex++; linearLayout.getChildAt(currentIndex % size).setEnabled( true ); couot++; handler.postDelayed( this , time); } }); } /** * 创建动画 */ private void createAnim() { outAnim = new ArrayList<>(); inAnim = new ArrayList<>(); for ( int i = 0 ; i < imageViews.size(); i++) { Animation zoomOutAwayAnim = createZoomOutAwayAnim(); zoomOutAwayAnim.setFillAfter( true ); outAnim.add(zoomOutAwayAnim); Animation zoomOutNearAnim = createZoomOutNearAnim(); zoomOutNearAnim.setFillAfter( true ); inAnim.add(zoomOutNearAnim); } } /** * 设置点击事件 */ public void setonClick() { for ( int i = 0 ; i < imageViews.size(); i++) { imageViews.get(i).setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { if (listner != null ) { listner.setonClick((currentIndex) % imageViews.size()); } } }); } } public interface onClickListner{ void setonClick( int position); } /** * 设置动画播放和handler延迟时间 * @param time */ public void setTime( long time) { this .time = time; } public void setListner(onClickListner listner) { this .listner = listner; } /** 创建一个淡出缩小的动画 */ public Animation createZoomOutAwayAnim() { AnimationSet ret; Animation anim; ret = new AnimationSet( false ); // 创建一个淡出的动画 anim = new AlphaAnimation(1f, 0f); anim.setDuration(time); anim.setInterpolator( new DecelerateInterpolator()); ret.addAnimation(anim); // 创建一个缩小的动画 /*anim = new ScaleAnimation(1, 0, 1, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(MEDIUM); anim.setInterpolator(new DecelerateInterpolator()); ret.addAnimation(anim);*/ return ret; } /** 创建一个淡入缩小的动画 */ public Animation createZoomOutNearAnim() { AnimationSet ret; Animation anim; ret = new AnimationSet( false ); // 创建一个淡入的动画 anim = new AlphaAnimation(0f, 1f); anim.setDuration(time); anim.setInterpolator( new LinearInterpolator()); ret.addAnimation(anim); // 创建一个缩小的动画 /*anim = new ScaleAnimation(3, 1, 3, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(MEDIUM); anim.setInterpolator(new DecelerateInterpolator()); ret.addAnimation(anim);*/ return ret; } } |
这个控件的使用非常简单只要在布局文件中使用我们自定义的控件,然后调用setTime设置动画切换的时间,setListener设置图片的点击事件,setImagevies设置图片就可以实现效果.考虑到内存泄漏的问题,只要在ondestry方法里面调用stop方法即可,点击下载Demo
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/totcw/article/details/52161975