Android實(shí)現(xiàn)viewpager實(shí)現(xiàn)循環(huán)輪播效果
在網(wǎng)上看到很多利用viewpager實(shí)現(xiàn)輪播都是通過設(shè)置一個(gè)很大的值,讓viewpager開始顯示在這個(gè)數(shù)值區(qū)間的中間,但這種輪播個(gè)人感覺不是真正的輪播,因此自己實(shí)現(xiàn)了一個(gè)輪播的效果。大致思路是這樣的,假如有5張圖adcde是要輪播展示的,這時(shí)創(chuàng)建一個(gè)新的集合eadcdea,然后再讓viewpager設(shè)置當(dāng)前展示第一張圖,也就是顯示a。這樣當(dāng)往左滑時(shí)顯示的是e,此時(shí)設(shè)置viewpager.setCurrentItem(5),當(dāng)右滑到e的時(shí)候在往右滑,此時(shí)設(shè)置viewpager.setCurrentItem(1),這樣就實(shí)現(xiàn)了輪播效果。
效果圖如下所示:

話不多說上一下代碼:
/**
* viewpager切換頁面時(shí)動畫
*/
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private ViewPaagerAdapter adapter;
private ArrayList<View> viewlist=new ArrayList<>();//承載圖片
private ArrayList<TextView> tvList=new ArrayList<>();//底部圓點(diǎn)集合
private int []imgList={R.drawable.img8,R.drawable.img1,R.drawable.img2,R.drawable.img3,R.drawable.img4,R.drawable.img5,
R.drawable.img6, R.drawable.img7,R.drawable.img8,R.drawable.img1};//圖片數(shù)組
boolean isStop=false;
private LinearLayout line;//小圓圈父視圖
private ScheduledThreadPoolExecutor executor;
private int currentPage;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
viewPager.setCurrentItem(msg.arg1);
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
viewPager= (ViewPager) findViewById(mybanner_viewpager);
line= (LinearLayout) findViewById(R.id.line);
setView();//設(shè)置輪播顯示的底圖
adapter=new ViewPaagerAdapter(this,viewlist);
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(1);
viewPager.setOffscreenPageLimit(10);//加這個(gè)是為了防止第一張往左滑動會出現(xiàn)閃爍
startService();//啟動輪播
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(final int position, float positionOffset, int positionOffsetPixels) {
Log.i("tag","位置"+position+"positionOffset"+positionOffset+"positionOffsetPixels"+positionOffsetPixels);
Log.i("tag","weizhi"+viewPager.getCurrentItem());
if (position==imgList.length-1) {
viewPager.setCurrentItem(1,false);
}else if(viewPager.getCurrentItem()==0&& positionOffsetPixels==0) {
viewPager.setCurrentItem(imgList.length-2, false);
}
currentPage=viewPager.getCurrentItem();
}
@Override
public void onPageSelected(final int position) {
Log.i("tag","位置wwwww"+position);
setEnbale();
if (position==imgList.length-1) {
tvList.get(0).setEnabled(true);
}
else if (position==0) {
tvList.get(imgList.length-3).setEnabled(true);
}
else{
tvList.get(position-1).setEnabled(true);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
public void setView() {
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(15,15);
params.leftMargin=10;
params.rightMargin=10;
for (int i = 0; i < imgList.length; i++) {
View view= LayoutInflater.from(this).inflate(R.layout.layout,null,false);
ImageView img= (ImageView) view.findViewById(R.id.img);
img.setBackgroundResource(imgList[i]);
TextView textView= (TextView) view.findViewById(R.id.tv);
textView.setText(i+"");
viewlist.add(view);
}
for (int i = 0; i < imgList.length-2; i++) {
TextView view=new TextView(this);
view.setBackgroundResource(R.drawable.item);
view.setLayoutParams(params);
view.setEnabled(false);
line.addView(view);
tvList.add(view);
}
tvList.get(0).setEnabled(true);
}
public void setEnbale(){
for (TextView tvcycle: tvList) {
tvcycle.setEnabled(false);
}
}
/**
* 啟動線程池開啟循環(huán)任務(wù)
*/
public void startService(){
executor=new ScheduledThreadPoolExecutor(1);
executor.scheduleWithFixedDelay(runnable,1,2, TimeUnit.SECONDS);
}
/**
* 停止任務(wù)
*/
public void stopService(){
executor.shutdown();
}
Runnable runnable=new Runnable() {
@Override
public void run() {
currentPage=currentPage+1%10;
Message message= Message.obtain();
message.what=1;
message.arg1=currentPage;
handler.sendMessage(message);
}
};
@Override
protected void onDestroy() {
super.onDestroy();
stopService();
}
}
實(shí)現(xiàn)輪播的重點(diǎn)在這:
if (position==imgList.length-1) {
viewPager.setCurrentItem(1,false);
}else if(viewPager.getCurrentItem()==0&& positionOffsetPixels==0) {
viewPager.setCurrentItem(imgList.length-2, false);
}
這里解釋一下onPageScrolled里三個(gè)參數(shù)的含義,第一個(gè)position,這個(gè)參數(shù)要特別注意一下。當(dāng)用手指滑動時(shí),如果手指按在頁面上不動,position和當(dāng)前頁面index是一致的;如果手指向左拖動(相應(yīng)頁面向右翻動),這時(shí)候position大部分時(shí)間和當(dāng)前頁面是一致的,只有翻頁成功的情況下最后一次調(diào)用才會變?yōu)槟繕?biāo)頁面;如果手指向右拖動(相應(yīng)頁面向左翻動),這時(shí)候position大部分時(shí)間和目標(biāo)頁面是一致的,只有翻頁不成功的情況下最后一次調(diào)用才會變?yōu)樵撁妗?
當(dāng)直接設(shè)置setCurrentItem翻頁時(shí),如果是相鄰的情況(比如現(xiàn)在是第二個(gè)頁面,跳到第一或者第三個(gè)頁面),如果頁面向右翻動,大部分時(shí)間是和當(dāng)前頁面是一致的,只有最后才變成目標(biāo)頁面;如果向左翻動,position和目標(biāo)頁面是一致的。這和用手指拖動頁面翻動是基本一致的。
如果不是相鄰的情況,比如我從第一個(gè)頁面跳到第三個(gè)頁面,position先是0,然后逐步變成1,然后逐步變成2;我從第三個(gè)頁面跳到第一個(gè)頁面,position先是1,然后逐步變成0,并沒有出現(xiàn)為2的情況。
positionOffset是當(dāng)前頁面滑動比例,如果頁面向右翻動,這個(gè)值不斷變大,最后在趨近1的情況后突變?yōu)?。如果頁面向左翻動,這個(gè)值不斷變小,最后變?yōu)?。positionOffsetPixels是當(dāng)前頁面滑動像素,變化情況和positionOffset一致。
這里采用線程池開啟了一個(gè)循環(huán)任務(wù),線程池的好處不說了,好了到此為止大概實(shí)現(xiàn)了viewpager的輪播了。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android使用ViewPager加載圖片和輪播視頻
- Android ViewPager實(shí)現(xiàn)輪播圖效果
- Android實(shí)現(xiàn)基于ViewPager的無限循環(huán)自動播放帶指示器的輪播圖CarouselFigureView控件
- Android實(shí)現(xiàn)帶指示器的自動輪播式ViewPager
- Android 使用ViewPager實(shí)現(xiàn)左右循環(huán)滑動及輪播效果
- Android 中使用 ViewPager實(shí)現(xiàn)屏幕頁面切換和頁面輪播效果
- Android中用RxJava和ViewPager實(shí)現(xiàn)輪播圖
- Android ViewPager實(shí)現(xiàn)圖片輪播效果
- Android使用ViewPager實(shí)現(xiàn)自動輪播
- Android 使用ViewPager自動滾動循環(huán)輪播效果
相關(guān)文章
Android中利用動態(tài)加載實(shí)現(xiàn)手機(jī)淘寶的節(jié)日特效
這篇文章主要介紹了Android中利用動態(tài)加載實(shí)現(xiàn)手機(jī)淘寶的節(jié)日特效,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12
Android實(shí)戰(zhàn)RecyclerView頭部尾部添加方法示例
本篇文章主要介紹了Android實(shí)戰(zhàn)RecyclerView頭部尾部添加方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11
flutter RotationTransition實(shí)現(xiàn)旋轉(zhuǎn)動畫
這篇文章主要為大家詳細(xì)介紹了flutter RotationTransition實(shí)現(xiàn)旋轉(zhuǎn)動畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
Android框架Volley使用之Json請求實(shí)現(xiàn)
這篇文章主要介紹了Android框架Volley使用之Json請求實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-05-05
Android音視頻開發(fā)之MediaPlayer使用教程
Android多媒體框架支持播放提供了MediaPlayerAPI,可以通過MediaPlayer來實(shí)現(xiàn)媒體文件播放??梢哉fMediaPlayer是非常方便使用的多媒體播放器。本文將詳細(xì)講解MediaPlayer的使用,需要的可以參考一下2022-04-04
Android ListView 實(shí)現(xiàn)上拉加載的示例代碼
這篇文章主要介紹了Android ListView 實(shí)現(xiàn)上拉加載的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07
Android HttpURLConnection.getResponseCode()錯(cuò)誤解決方法
在使用HttpURLConnection.getResponseCode()的時(shí)候直接報(bào)錯(cuò)是IOException錯(cuò)誤,一直想不明白,同一個(gè)程序我調(diào)用了兩次,結(jié)果有一個(gè)鏈接一直O(jiān)K,另一個(gè)卻一直報(bào)這個(gè)錯(cuò)誤2013-06-06

