Android實(shí)現(xiàn)viewpager實(shí)現(xiàn)循環(huán)輪播效果
在網(wǎng)上看到很多利用viewpager實(shí)現(xiàn)輪播都是通過(guò)設(shè)置一個(gè)很大的值,讓viewpager開(kāi)始顯示在這個(gè)數(shù)值區(qū)間的中間,但這種輪播個(gè)人感覺(jué)不是真正的輪播,因此自己實(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)了輪播效果。
效果圖如下所示:
話不多說(shuō)上一下代碼:
/** * viewpager切換頁(yè)面時(shí)動(dòng)畫(huà) */ 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è)是為了防止第一張往左滑動(dòng)會(huì)出現(xiàn)閃爍 startService();//啟動(dòng)輪播 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); } } /** * 啟動(dòng)線程池開(kāi)啟循環(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)用手指滑動(dòng)時(shí),如果手指按在頁(yè)面上不動(dòng),position和當(dāng)前頁(yè)面index是一致的;如果手指向左拖動(dòng)(相應(yīng)頁(yè)面向右翻動(dòng)),這時(shí)候position大部分時(shí)間和當(dāng)前頁(yè)面是一致的,只有翻頁(yè)成功的情況下最后一次調(diào)用才會(huì)變?yōu)槟繕?biāo)頁(yè)面;如果手指向右拖動(dòng)(相應(yīng)頁(yè)面向左翻動(dòng)),這時(shí)候position大部分時(shí)間和目標(biāo)頁(yè)面是一致的,只有翻頁(yè)不成功的情況下最后一次調(diào)用才會(huì)變?yōu)樵?yè)面。
當(dāng)直接設(shè)置setCurrentItem翻頁(yè)時(shí),如果是相鄰的情況(比如現(xiàn)在是第二個(gè)頁(yè)面,跳到第一或者第三個(gè)頁(yè)面),如果頁(yè)面向右翻動(dòng),大部分時(shí)間是和當(dāng)前頁(yè)面是一致的,只有最后才變成目標(biāo)頁(yè)面;如果向左翻動(dòng),position和目標(biāo)頁(yè)面是一致的。這和用手指拖動(dòng)頁(yè)面翻動(dòng)是基本一致的。
如果不是相鄰的情況,比如我從第一個(gè)頁(yè)面跳到第三個(gè)頁(yè)面,position先是0,然后逐步變成1,然后逐步變成2;我從第三個(gè)頁(yè)面跳到第一個(gè)頁(yè)面,position先是1,然后逐步變成0,并沒(méi)有出現(xiàn)為2的情況。
positionOffset是當(dāng)前頁(yè)面滑動(dòng)比例,如果頁(yè)面向右翻動(dòng),這個(gè)值不斷變大,最后在趨近1的情況后突變?yōu)?。如果頁(yè)面向左翻動(dòng),這個(gè)值不斷變小,最后變?yōu)?。positionOffsetPixels是當(dāng)前頁(yè)面滑動(dòng)像素,變化情況和positionOffset一致。
這里采用線程池開(kāi)啟了一個(gè)循環(huán)任務(wù),線程池的好處不說(shuō)了,好了到此為止大概實(shí)現(xiàn)了viewpager的輪播了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android使用ViewPager加載圖片和輪播視頻
- Android ViewPager實(shí)現(xiàn)輪播圖效果
- Android實(shí)現(xiàn)基于ViewPager的無(wú)限循環(huán)自動(dòng)播放帶指示器的輪播圖CarouselFigureView控件
- Android實(shí)現(xiàn)帶指示器的自動(dòng)輪播式ViewPager
- Android 使用ViewPager實(shí)現(xiàn)左右循環(huán)滑動(dòng)及輪播效果
- Android 中使用 ViewPager實(shí)現(xiàn)屏幕頁(yè)面切換和頁(yè)面輪播效果
- Android中用RxJava和ViewPager實(shí)現(xiàn)輪播圖
- Android ViewPager實(shí)現(xiàn)圖片輪播效果
- Android使用ViewPager實(shí)現(xiàn)自動(dòng)輪播
- Android 使用ViewPager自動(dòng)滾動(dòng)循環(huán)輪播效果
相關(guān)文章
Android多媒體應(yīng)用使用MediaPlayer播放音頻
這篇文章主要為大家詳細(xì)介紹了Android多媒體應(yīng)用使用MediaPlayer播放音頻,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12雙緩沖技術(shù)實(shí)現(xiàn)Android 畫(huà)板應(yīng)用
這篇文章主要介紹了Android 采用雙緩存技術(shù)實(shí)現(xiàn)畫(huà)板應(yīng)用的相關(guān)資料,并附有代碼實(shí)例,有需要的小伙伴可以參考下2016-07-07Android自定義view實(shí)現(xiàn)圓環(huán)進(jìn)度條效果
這篇文章主要為大家詳細(xì)介紹了Android自定義view實(shí)現(xiàn)圓環(huán)進(jìn)度條效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02android數(shù)據(jù)存儲(chǔ)之文件存儲(chǔ)方法
本篇文章主要介紹了android數(shù)據(jù)存儲(chǔ)之文件存儲(chǔ)的方法,具有一定的參考價(jià)值,有需要的可以了解一下。2016-11-11Android 實(shí)現(xiàn)單線程輪循機(jī)制批量下載圖片
這篇文章主要介紹了Android 單線程輪循機(jī)制批量下載圖片的相關(guān)資料,這里對(duì)實(shí)現(xiàn)步驟做了詳細(xì)介紹,需要的朋友可以參考下2017-07-07Android開(kāi)發(fā)實(shí)戰(zhàn)鬧鐘項(xiàng)目
這篇文章主要介紹了Android開(kāi)發(fā)實(shí)戰(zhàn)鬧鐘項(xiàng)目,根據(jù)我們手機(jī)鬧鐘設(shè)計(jì)的一個(gè)鬧鐘APP,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09Android之自定義實(shí)現(xiàn)BaseAdapter(通用適配器二)
這篇文章主要為大家詳細(xì)介紹了Android之自定義實(shí)現(xiàn)BaseAdapter通用適配器第二篇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08