网络上有很多无线循环的Viewpager,但是学习嘛,就自己写了一个无线循环的ViewPager。
思路一
网上有一种是真正意义的无限循环,比如View0,View1,View2,View3, 4个View,
在View0左侧加一个View3,View3右侧加一个View0,
就成了View3-2, View0,View1,View2,View3, View0-2,
View3向右滑动,显示的是View0-2,viewPager.setCurrentItem(position,fasle)这个方法跳到View0,
同理View0左滑,显示的是View3-2,同样跳到View3,
这个方法的缺点就是,View0到View3滑动时流畅的,但是View3到View0,是瞬间变化的,不好看。
思路二
Adapter,getCount()设置为 Integer.MAX_VALUE ,这是一个非常非常大的数,
然后我们一进去就取中间值,无论左滑还是右滑,都能不停的循环加载View,
这些view也是重复使用的,因为这个数非常大,
所以你不会那么无聊,一直挂机,挂到他到底吧,所以就能模拟成无线循环,
而且界面的切换也是如丝般顺滑,我比较倾斜这个算法。
切换动画是出自鸿洋大神的
出自:http://blog.csdn.net/lmj623565791/article/details/40411921
小圆圈样式
1
2
3
4
5
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<item android:drawable=
"@drawable/advertisement_circle_1"
android:state_checked=
"true"
/>
<item android:drawable=
"@drawable/advertisement_circle_2"
android:state_checked=
"false"
/>
</selector>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<shape
android:shape=
"oval"
<solid
android:color=
"#FFFFFF"
/>
<size
android:width=
"15dp"
android:height=
"15dp"
/>
</shape>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<shape
android:shape=
"oval"
<solid
android:color=
"#22FFFFFF"
/>
<stroke
android:width=
"1dp"
android:color=
"#FFFFFF"
/>
<size
android:width=
"15dp"
android:height=
"15dp"
/>
</shape>
|
Viewpager动画
DepthPageTransformer
这个是出于鸿洋大神的:http://blog.csdn.net/lmj623565791/article/details/40411921
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
|
public
class
DepthPageTransformer
implements
ViewPager.PageTransformer
{
private
static
final
float
MIN_SCALE =
0
.75f;
public
void
transformPage(View view,
float
position)
{
int
pageWidth = view.getWidth();
if
(position < -
1
)
{
// [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(
0
);
}
else
if
(position <=
0
)
{
// [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(
1
);
view.setTranslationX(
0
);
view.setScaleX(
1
);
view.setScaleY(
1
);
}
else
if
(position <=
1
)
{
// (0,1]
// Fade the page out.
view.setAlpha(
1
- position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float
scaleFactor = MIN_SCALE
+ (
1
- MIN_SCALE) * (
1
- Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
}
else
{
// (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(
0
);
}
}
}
|
LoopViewAdapter,这样写,就一定要用这个Adapter
1
2
3
4
5
6
7
8
|
/**
* 要用LoopView一定要使用这个Adapter
*/
public
abstract
class
MyLoopViewAdapter
extends
PagerAdapter
{
/**
* 返回真实的view数
*/
public
abstract
int
getRealCount();
}
|
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
|
public
class
LoopViewAdapter
extends
MyLoopViewAdapter
{
private
ArrayList<View> views =
new
ArrayList<>();
public
LoopViewAdapter()
{
}
public
LoopViewAdapter(ArrayList<View> views)
{
this
.views = views;
}
/**
* 在下标position处添加View
*/
public
void
insertView(View view,
int
position)
{
if
(view !=
null
)
{
this
.views.add(position, view);
notifyDataSetChanged();
}
}
/**
* 在尾部添加view
*/
public
void
insertView(View view)
{
if
(view !=
null
)
{
this
.views.add(view);
notifyDataSetChanged();
}
}
/**
* 获取view
*/
public
View getView(
int
position)
{
return
this
.views.get(position);
}
@Override
public
int
getCount()
{
//设置为一个很大很大的数
return
Integer.MAX_VALUE;
}
@Override
public
int
getRealCount()
{
return
views.size();
}
@Override
public
Object instantiateItem(
final
ViewGroup container,
int
position)
{
final
View view = views.get(position % (views.size()));
//在主线程添加
container.post(
new
Runnable()
{
@Override
public
void
run()
{
container.removeView(view);
container.addView(view);
}
});
return
view;
}
@Override
public
void
destroyItem(ViewGroup container,
int
position, Object object)
{
}
@Override
public
boolean
isViewFromObject(View view, Object object)
{
return
view == object;
}
}
|
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
|
/**
* Created by solexit04 on 2016/8/17.
* 自动轮播Viewpager
*/
public
class
LoopViewPager
extends
RelativeLayout
implements
ViewPager.OnPageChangeListener
{
//底部小圆圈的样式
private
int
dotRes = -
1
;
//图片轮转周期
private
int
period =
2000
;
private
static
final
int
ADVERTISEMENT =
1
;
private
ViewPager viewPager;
private
RadioGroup radioGroup;
private
LoopViewAdapter loopViewAdapter;
public
LoopViewPager(Context context)
{
this
(context,
null
);
}
public
LoopViewPager(Context context, AttributeSet attrs)
{
this
(context, attrs,
0
);
}
public
LoopViewPager(Context context, AttributeSet attrs,
int
defStyleAttr)
{
super
(context, attrs, defStyleAttr);
init();
}
private
Handler handler =
new
Handler(
new
Handler.Callback()
{
@Override
public
boolean
handleMessage(Message msg)
{
switch
(msg.what)
{
case
ADVERTISEMENT:
viewPager.setCurrentItem(viewPager.getCurrentItem() +
1
);
handler.sendEmptyMessageDelayed(ADVERTISEMENT, period);
break
;
default
:
break
;
}
return
false
;
}
});
/**
* 初始化控件
*/
private
void
init()
{
viewPager =
new
ViewPager(getContext());
viewPager.addOnPageChangeListener(
this
);
radioGroup =
new
RadioGroup(getContext());
//设置RadioGroup为水平排列
radioGroup.setOrientation(RadioGroup.HORIZONTAL);
//让viewpager填充满怎个布局
RelativeLayout.LayoutParams params =
new
LayoutParams(LayoutParams.MATCH_PARENT
, LayoutParams.MATCH_PARENT);
viewPager.setLayoutParams(params);
addView(viewPager);
//设置radioGroup包裹内容
params =
new
LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//设置为水平居中
params.addRule(CENTER_HORIZONTAL);
//设置为父布局的底部
params.addRule(ALIGN_PARENT_BOTTOM);
radioGroup.setLayoutParams(params);
addView(radioGroup);
}
/**
* 设置小圆点的样式
*/
public
void
setDotRes(
int
dotRes)
{
this
.dotRes = dotRes;
if
(dotRes ==
0
)
{
return
;
}
for
(
int
i =
0
; i < radioGroup.getChildCount(); i++)
{
radioGroup.getChildAt(i).setBackgroundResource(dotRes);
}
}
/**
* 设置底部小圆点RadioGroup是否可见
*/
public
void
setDotVisible(
boolean
visible)
{
if
(visible)
{
radioGroup.setVisibility(VISIBLE);
}
else
{
radioGroup.setVisibility(GONE);
}
}
/**
* 设置轮播间隔
*/
public
void
setPeriod(
int
period)
{
this
.period = period;
}
/**
* 设置是否开始滚动
*/
public
void
startLoop()
{
//先移除,防止重复加载
stopLoop();
//发送延时消息
handler.sendEmptyMessageDelayed(ADVERTISEMENT, period);
}
/**
* 停止滚动
*/
public
void
stopLoop()
{
handler.removeMessages(ADVERTISEMENT);
}
/**
* 返回当前页码
*/
public
int
getCurrentItem()
{
return
viewPager.getCurrentItem() % loopViewAdapter.getRealCount();
}
/**
* 设置适配器
*/
public
void
setAdapter(LoopViewAdapter adapter)
{
if
(adapter ==
null
)
{
return
;
}
this
.loopViewAdapter = adapter;
int
count = adapter.getRealCount();
//根据适配器的图片数量,设置小圆点的数量
for
(
int
i =
0
; i < count; i++)
{
RadioButton radioButton =
new
RadioButton(getContext());
//给RadioButton一个空的BitmapDrawable对象,骗过setButtonDrawable的过滤,实际上绘制的时候是没有图片资源
//将RadioButton的小圆点去掉
radioButton.setButtonDrawable(
new
ColorDrawable());
//设置不能点击
radioButton.setEnabled(
false
);
//设置小圆点的尺寸
RadioGroup.LayoutParams params =
new
RadioGroup.LayoutParams(
15
,
15
);
//设置小圆点的间距
params.setMargins(
0
,
0
,
10
,
20
);
radioButton.setLayoutParams(params);
//设置背景样式
if
(dotRes != -
1
)
{
radioButton.setBackgroundResource(dotRes);
}
else
{
radioButton.setBackgroundResource(R.drawable.advertisement_circle);
}
radioGroup.addView(radioButton);
}
//第一个显示为已选定
RadioButton radioButton = (RadioButton) radioGroup.getChildAt(
0
);
radioButton.setChecked(
true
);
viewPager.setAdapter(loopViewAdapter);
//设置viewPager切换动画
viewPager.setPageTransformer(
true
,
new
DepthPageTransformer());
//每次打开都会显示Viewpager第一页
viewPager.setCurrentItem((loopViewAdapter.getCount() /
2
) -
(loopViewAdapter.getCount() /
2
) % loopViewAdapter.getRealCount());
}
@Override
public
void
onPageScrolled(
int
position,
float
positionOffset,
int
positionOffsetPixels)
{
}
@Override
public
void
onPageSelected(
int
position)
{
RadioButton radioButton = (RadioButton) radioGroup
.getChildAt(position % loopViewAdapter.getRealCount());
radioButton.setChecked(
true
);
}
@Override
public
void
onPageScrollStateChanged(
int
state)
{
switch
(state)
{
//手拖住就停止计时
case
ViewPager.SCROLL_STATE_DRAGGING:
stopLoop();
break
;
//松开继续继续计时
case
ViewPager.SCROLL_STATE_IDLE:
startLoop();
break
;
default
:
break
;
}
}
}
|
使用
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
|
public
class
LoopViewPagerActivity
extends
AppCompatActivity
{
private
LoopViewPager loopViewPager;
private
LoopViewAdapter loopViewAdapter;
@Override
protected
void
onCreate(Bundle savedInstanceState)
{
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_view);
initView();
}
private
void
initView()
{
loopViewPager = (LoopViewPager) findViewById(R.id.advertisementViewPager);
//设置间隔,默认2秒,默认开启循环
loopViewPager.setPeriod(
3000
);
initAdapter(getImages());
loopViewPager.setAdapter(loopViewAdapter);
}
private
void
initAdapter(ArrayList<String> images)
{
final
ArrayList<View> views =
new
ArrayList<>();
for
(
int
i =
0
; i <
5
; i++)
{
View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item,
null
);
final
TextView textView = (TextView) view.findViewById(R.id.item_tv);
textView.setText(
"Mo.nica "
+ i);
ImageView imageView = (ImageView) view.findViewById(R.id.item_image);
//Glide加载图片
Glide.with(getApplicationContext())
.load(images.get(i))
.into(imageView);
textView.setOnClickListener(
new
View.OnClickListener()
{
@Override
public
void
onClick(View v)
{
Toast.makeText(LoopViewPagerActivity.
this
, textView.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
view.setOnClickListener(
new
View.OnClickListener()
{
@Override
public
void
onClick(View v)
{
Toast.makeText(LoopViewPagerActivity.
this
,
""
+ loopViewPager.getCurrentItem(), Toast.LENGTH_SHORT).show();
if
(loopViewPager.getCurrentItem() == views.size() -
1
)
{
finish();
}
}
});
views.add(view);
}
loopViewAdapter =
new
LoopViewAdapter(views);
}
private
ArrayList<String> getImages()
{
ArrayList<String> images =
new
ArrayList<>();
return
images;
}
}
|
最后,给上源码,下载地址(
下载源码):
http://download.csdn.net/detail/u013365445/9608109
大家一起学习,哈。