• 一行代码引入 ViewPager 无限循环 + 页码显示


    (出处:http://www.cnblogs.com/linguanh)

    前序:

      网上的这类 ViewPager 很多,但是很多都不够好,体现在 bug多、对少页面不支持,例如1~2张图片、功能整合不全(无限+页码)等等,本类由我从零到无完成的,基本已找完 bug,注释丰富,方便大家理解。

    特点:

      1,代码量少 , 共两个类,约合 310 行代码 (除去注释)

      2,可扩展 , 再加个 handler 即可实现自动轮播

      3,时间复杂度低

      4,耦合度低,只依赖了 imageLoader,可以自己切换

      5,关键点皆给出了详细注释,方便二次开发

    功能:

      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

     
     
  • 相关阅读:
    Vsftp的PASV mode(被动模式传送)和Port模式及 Linux下VsFTP配置全方案
    vsftpd:500 OOPS: vsftpd: refusing to run with writable root inside chroot ()错误的解决方法
    CentOS7.2部署FTP
    Apache与Nginx的优缺点比较
    MySQL存储引擎--MyISAM与InnoDB区别
    CentOS 7下搭建配置SVN服务器
    Remi 安装源
    tmpx75 I2C 温度传感器驱动程序添加
    QT 5.7.0 交叉编译记录
    am335x SGX 移植
  • 原文地址:https://www.cnblogs.com/linguanh/p/5372753.html
Copyright © 2020-2023  润新知