一行代碼引入 ViewPager 無限循環 + 頁碼顯示

(出處:http://www.cnblogs.com/linguanh)android

 

前序:git

  網上的這類 ViewPager 不少,可是不少都不夠好,體如今 bug多、對少頁面不支持,例如1~2張圖片、功能整合不全(無限+頁碼)等等,本類由我從零到無完成的,基本已找完 bug,註釋豐富,方便你們理解。github

 

特色:數組

  1,代碼量少 , 共兩個類,約合 310 行代碼 (除去註釋)app

  2,可擴展 , 再加個 handler 便可實現自動輪播ide

  3,時間複雜度低oop

  4,耦合度低,只依賴了 imageLoader,能夠本身切換佈局

  5,關鍵點皆給出了詳細註釋,方便二次開發ui

 

功能:this

  1,右滑無限循環(2^32,或更大),支持頁面數>=2, 左滑循環直至原始第一張;

  2,上述效果伴隨着正確的頁面小點顯示,具體效果可自定義

 

使用:

      // 第一個參數是 Activity;第二個是 ViewPager 對象;第三個是 imageLoader 實例,若使用本身的方法加載圖片,請修改代碼;第四個是圖片連接字符串數組  

       new MyViewPager(this,viewpager,imageLoder,imageUrls) 

             .setUnClickLooper(true) // 設置開啓第一種效果的無限循環

             .setClickLooper(true)    //  設置開啓第二種效果的無限循環

             .init();                         //  實例化所有  

 

效果圖:

  第一類效果,佈局嵌套時,縮略圖形式顯示滑動

  

  第二類效果,點擊單張圖片進入 dialog 風格,大圖顯示形式

 

 

類簡介:

  上述兩種效果都能本身選擇是否開啓無限滑動。

  LoopViewpagerAdapter 類,繼承於 PagerAdapter,主要實現功能是無限循環,邏輯處理比較集中於此,經過接口方式加載頁 View。
  1 package cn.share.bananacloud.coustomViews.coustomEdittextInput.MyViewPager;
  2 
  3 import android.app.Activity;
  4 import android.support.v4.view.PagerAdapter;
  5 import android.util.Log;
  6 import android.view.LayoutInflater;
  7 import android.view.View;
  8 import android.view.ViewGroup;
  9 
 10 /**
 11  * Created by 林冠宏 on 2016/4/9.
 12  *
 13  * viewPager 無限循環
 14  *
 15  */
 16 
 17 public class LoopViewpagerAdapter extends PagerAdapter{
 18 
 19     private int images;
 20     private String[] imageUrls;
 21     private View[] views;
 22     private boolean isLooper;
 23     private LayoutInflater layoutInflater;
 24     private getItemViewListener getItemViewListener;
 25 
 26     public LoopViewpagerAdapter(
 27             Activity activity,
 28             String[] imageUrls,
 29             boolean isLooper, /** 是否進行無限循環 */
 30             getItemViewListener getItemViewListener)
 31     {
 32         this.isLooper = isLooper;
 33         this.images = imageUrls.length;
 34         this.layoutInflater = activity.getLayoutInflater();
 35         this.imageUrls = imageUrls;
 36         views = new View[images];
 37         this.getItemViewListener = getItemViewListener;
 38     }
 39 
 40     @Override
 41     public int getCount() {
 42         if(isLooper){
 43             if(images<3){ /** 1~2 張圖片的狀況 強制不開啓循環 */
 44                 return images;
 45             }else {
 46                 return 65535; /** 設置足夠大 2^32 */
 47             }
 48         }else{
 49             return images;
 50         }
 51     }
 52 
 53     /** 調用順序 destroyItem -> instantiateItem */
 54 
 55     @Override
 56     public void destroyItem(ViewGroup container, int position, Object object) {
 57         Log.d("zzzzz","destroy "+position);
 58         container.removeView((View) object); /** 和 instantiateItem 相照應,這個是移除,不用擔憂內存會累加 */
 59     }
 60 
 61     @Override
 62     public Object instantiateItem(ViewGroup container,int position) {
 63         Log.d("zzzzz", "position " + position);
 64         if(isLooper && images==3){
 65             /** 3張的特殊處理,在先右滑了必定張數後,再左滑,此時初始化的 距離當前位置 的第前2張和後面一張會重複 (x-2) == (x+1) */
 66             View view = getItemViewListener.getItemView(layoutInflater, container, imageUrls[position%images], position);
 67             container.addView(view);
 68             return view;
 69         }else {
 70             if (position < images) {
 71                 if (views[position] == null) {
 72                     views[position] = getItemViewListener.getItemView(layoutInflater, container, imageUrls[position], position);
 73                 }
 74             } else if (position == images && isLooper) { /** 解決由 setCurrentItem 引起的問題 */
 75                 /** 時間複雜度不高,每通過一次,進入一次 */
 76                 /** 若是看大圖vp 從臨界最大值點擊進來,此時沒有以前的 view 賦值,直接 view[max-1] 會形成 空指針 exception,這是會初始化的有 max-2,max,max-1 */
 77                 /*if(images>2){ // 最小狀況的判斷,由於此時的 container 尚未移除下標 0 的圖片,再添加的話會形成不能重複添加的異常
 78                     views[0] = getItemViewListener.getItemView(layoutInflater,container,imageUrls[0],0);
 79                 }else{ // 恰好是 2 張,手動移除下標 0
 80 
 81                 }*/
 82                 /** 若是 共4張圖,此時 positon = 3 setCurrentItem() 就會形成加載了 4-2,4,4-1,4 在 view[] 是越界狀態,故須要手動賦值 0,2和3 也初始化了,可是 1 沒
 83                  *  若一直右滑,到 下標 1 便會拋 Cannot add a null child view to a ViewGroup,因此要 加上 views[images - 3] 也初始化
 84                  * */
 85                 views[0] = getItemViewListener.getItemView(layoutInflater, container, imageUrls[0], 0);
 86                 views[images - 3] = getItemViewListener.getItemView(layoutInflater, container, imageUrls[images - 3], 0);
 87                 container.addView(views[0]);  /** add 0 不會有問題, */
 88                 return views[0];
 89             }
 90         }
 91 
 92         container.addView(views[position%images]);
 93         return views[position%images];
 94     }
 95 
 96     @Override
 97     public boolean isViewFromObject(View view, Object o){
 98         return view.equals(o);
 99     }
100 
101     public interface getItemViewListener{
102         View getItemView(LayoutInflater layoutInflater,ViewGroup container,final String url,final int position);
103     }
104 
105 }
View Code

  

  MyViewPager 類,無父類,內部使用了 LoopViewpagerAdapter ,在無限循環的基礎上,附加實現了頁碼小點的顯示。
  1 package cn.share.bananacloud.coustomViews.coustomEdittextInput.MyViewPager;
  2 
  3 import android.app.Activity;
  4 import android.app.AlertDialog;
  5 import android.graphics.Bitmap;
  6 import android.support.v4.view.ViewPager;
  7 import android.util.Log;
  8 import android.view.LayoutInflater;
  9 import android.view.MotionEvent;
 10 import android.view.View;
 11 import android.view.ViewGroup;
 12 import android.view.Window;
 13 import android.widget.ImageView;
 14 import android.widget.LinearLayout;
 15 import android.widget.ProgressBar;
 16 import android.widget.TextView;
 17 
 18 import com.nostra13.universalimageloader.core.ImageLoader;
 19 import com.nostra13.universalimageloader.core.assist.FailReason;
 20 import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
 21 
 22 import cn.share.bananacloud.R;
 23 import cn.share.bananacloud.common.commonDataHelper;
 24 import cn.share.bananacloud.coustomViews.coustomEdittextInput.zoomImageView.PhotoView;
 25 import cn.share.bananacloud.tools.imageLoderHelper;
 26 
 27 /**
 28  * Created by 林冠宏 on 2016/4/9.
 29  *
 30  * viewPager 無限滑動 + 點擊看大圖,仍可滑動 + 當前張號頁碼
 31  *
 32  */
 33 
 34 public class MyViewPager {
 35 
 36     private Activity activity;
 37     private String[] imageUrls;
 38     protected ImageLoader imageLoder = null;
 39     private ViewPager viewPager;
 40     private int limitTemp = 0; /** 臨界中間值 */
 41     private int picnum;
 42     private boolean unClickLooper = false;
 43     private boolean ClickLooper = false;
 44 
 45     public MyViewPager(
 46             Activity activity,
 47             ViewPager viewPager,
 48             ImageLoader imageLoder,
 49             String[] imageUrls
 50     ){
 51         this.activity = activity;
 52         this.imageUrls = imageUrls;
 53         this.imageLoder = imageLoder;
 54         this.viewPager = viewPager;
 55         picnum = imageUrls.length;
 56     }
 57 
 58     public MyViewPager setUnClickLooper(boolean unClickLooper){
 59         this.unClickLooper = unClickLooper;
 60         return this;
 61     }
 62 
 63     public MyViewPager setClickLooper(boolean ClickLooper){
 64         this.ClickLooper = ClickLooper;
 65         return this;
 66     }
 67 
 68     public void init(){
 69         viewPager.setAdapter
 70                 (
 71                         new LoopViewpagerAdapter
 72                                 (
 73                                         activity,
 74                                         imageUrls,
 75                                         unClickLooper,
 76                                         new LoopViewpagerAdapter.getItemViewListener() {
 77                                             @Override
 78                                             public View getItemView(LayoutInflater layoutInflater, ViewGroup container, final String url, final int position) {
 79                                                 View view = layoutInflater.inflate(R.layout.cy_item_main_image, container, false);
 80                                                 ImageView imageView = (ImageView) view.findViewById(R.id.image);
 81                                                 imageView.setOnClickListener(new View.OnClickListener() {
 82                                                     @Override
 83                                                     public void onClick(View v) {
 84                                                         int temp = position%picnum; /** 記得取餘數 position 在無限循環的模式不是 0 ~ picnum */
 85                                                         if(temp==0 && position!=0){
 86                                                             showVPimage(picnum-1);
 87                                                         }else{
 88                                                             showVPimage(temp);
 89                                                         }
 90 
 91                                                     }
 92                                                 });
 93                                                 final ProgressBar spinner = (ProgressBar) view.findViewById(R.id.loading);
 94 
 95                                                 imageLoder.displayImage(url, imageView,
 96                                                         imageLoderHelper.getLoderOption(commonDataHelper.phoneWidth, R.drawable.hot_live_default_image, 0), new SimpleImageLoadingListener() {
 97                                                             @Override
 98                                                             public void onLoadingStarted(String imageUri, View view) {
 99                                                                 spinner.setVisibility(View.VISIBLE);
100                                                                 Log.d("zzzzz", "onLoadingStarted");
101                                                             }
102 
103                                                             @Override
104                                                             public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
105                                                                 spinner.setVisibility(View.GONE);
106                                                             }
107 
108                                                             @Override
109                                                             public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
110                                                                 Log.d("zzzzz", "onLoadingComplete "+imageUri);
111                                                                 spinner.setVisibility(View.GONE);
112                                                             }
113                                                         });
114                                                 return view;
115                                             }
116                                         }
117                                 )
118                 );
119 
120         viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
121             @Override
122             public void onPageScrolled(int i, float v, int i1) {
123 
124             }
125 
126             @Override
127             public void onPageSelected(int i) { /** 先於 instantiateItem 執行 */
128                 TextView nowCount = (TextView) activity.findViewById(R.id.nowCount);
129                 if((i+1)%picnum==0){
130                     nowCount.setText("" + picnum + " /");
131                 }else {
132                     nowCount.setText("" + (i + 1) % picnum + " /");
133                 }
134             }
135 
136             @Override
137             public void onPageScrollStateChanged(int i) {
138 
139             }
140         });
141     }
142 
143     private void showVPimage(int positon) {
144         final AlertDialog dlg = new AlertDialog.Builder(activity).create();
145 
146         View localView = LayoutInflater.from(activity).inflate(R.layout.viewpager, null);
147 
148         localView.setOnTouchListener(new View.OnTouchListener() {
149             @Override
150             public boolean onTouch(View v, MotionEvent event) {
151                 dlg.dismiss();
152                 return false;
153             }
154         });
155 
156         ViewPager viewPager = (ViewPager) localView.findViewById(R.id.imageContainer);
157         final LinearLayout pointContainer = (LinearLayout) localView.findViewById(R.id.pointContainer);
158         for(int i=0;i<picnum;i++){
159             ImageView imageView = (ImageView) LayoutInflater.from(activity).inflate(R.layout.viewpager_point,pointContainer,false);
160             pointContainer.addView(imageView);
161         }
162         viewPager.setAdapter
163                 (
164                         new LoopViewpagerAdapter
165                                 (
166                                         activity,
167                                         imageUrls,
168                                         ClickLooper,
169                                         new LoopViewpagerAdapter.getItemViewListener() {
170                                             @Override
171                                             public View getItemView(LayoutInflater layoutInflater, ViewGroup container, String url, int position) {
172                                                 View view = layoutInflater.inflate(R.layout.show_big_pic, container, false);
173                                                 PhotoView imageView = (PhotoView) view.findViewById(R.id.bigImage);
174                                                 imageView.setdimissDialog(new PhotoView.dimissDialog() {
175                                                     @Override
176                                                     public void doDimissDialog() {
177                                                         dlg.dismiss();
178                                                     }
179                                                 });
180                                                 try {
181                                                     imageLoder.displayImage
182                                                             (
183                                                                     url,
184                                                                     imageView,
185                                                                     imageLoderHelper.getLoderOption(commonDataHelper.phoneWidth+50, R.drawable.hot_live_default_image,0)
186                                                             );
187                                                 } catch (Exception ignored){}
188                                                 return view;
189                                             }
190                                         }
191                                 )
192                 );
193         viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
194             @Override
195             public void onPageScrolled(int i, float v, int i1) {
196 
197             }
198 
199             @Override
200             public void onPageSelected(int i) { /** 先於 instantiateItem 執行 */
201                 Log.d("onPageSelected","onPageSelected ->"+i);
202                 /** 爲了減小 CPU 和 內存的 繪圖消耗,這裏不採用 for 等循環的方式改 點背景,改用條件語句 */
203                 if(ClickLooper){
204                     Log.d("onPageSelected","i is ->"+i +" limitTemp is "+limitTemp);
205                     /** 循環狀況臨界點的顏色恢復 */
206                     if((i % picnum)==(picnum-1) && limitTemp == 0){  /** 左滑 */
207                         ((ImageView) pointContainer.getChildAt(0)).setImageResource(R.drawable.white_point_xml);
208                     }else {
209                         if (i >= picnum && i % picnum == 0) { /** 右滑 */
210                             ((ImageView) pointContainer.getChildAt(picnum - 1)).setImageResource(R.drawable.white_point_xml);
211                         }
212                     }
213                 }
214                 i = i % picnum;
215                 ((ImageView) pointContainer.getChildAt(i)).setImageResource(R.drawable.color_point);
216                 if (i != 0 && i != picnum - 1) { /** 非臨界值,兩邊都要修改 */
217                     ((ImageView) pointContainer.getChildAt(i>limitTemp ? i-1:i+1)).setImageResource(R.drawable.white_point_xml);
218                 }else {
219                     ((ImageView) pointContainer.getChildAt(i==picnum-1 ? i-1:i+1)).setImageResource(R.drawable.white_point_xml);
220                 }
221                 limitTemp = i;
222             }
223 
224             @Override
225             public void onPageScrollStateChanged(int i) {
226 
227             }
228         });
229         viewPager.setCurrentItem(positon);
230         ((ImageView)pointContainer.getChildAt(positon)).setImageResource(R.drawable.color_point);
231 
232 
233         Window localWindow = dlg.getWindow();
234         localWindow.getAttributes();
235         dlg.show();
236         localWindow.setContentView(localView);
237         localWindow.setGravity(17);
238         localWindow.setLayout(-1, -1);
239     }
240 
241 }
View Code

 

Demo項目 github 連接:

  https://github.com/af913337456/lghLoopViewPager?files=1

相關文章
相關標籤/搜索