zoukankan      html  css  js  c++  java
  • 无限循环的ViewPager

    目前情况

    在不修改源码的情况下,当ViewPager滑动到最后一个item的时候,他就无法再往右滑动;当ViewPager滑动到第一个item的时候,他也无法再往前滑动。(以上全是废话)

    设想

    我们可以这样想,当滑动最后一个的时候,我们让他跳转到第一个,这样他就可以继续往后滑动了,这样做行程了我们想要的循环滑动。

    如果这样作,虽然功能上是循环了,但是实际显示的时候会在最后一个和第一个之间自动跳转。

    优化

    我们可以在原来的链表中首尾各增加一个假的item,用多余的两个item来作跳转的动作,这样就可以避免出现自动跳转的错误画面了。请看下面演示。

    我们要显示的是下面A、B、C画面,位置分别是0、1、2.

     

    实际上,我们添加数据的时候,多添加了2个。在位置0添加了最后一个界面C,在位置4添加了第一个界面A。

     

    当界面滑动到位置3的时候,他还可以往右滑动,这样给人的感觉就是循环的。但,当滑动到位置4的时候,他右边没有了,这样岂不是露馅了?所以,当滑动到位置4的时候,立刻跳转到位置1。因为他们是同样的数据,所以从显示效果是看不出跳转了的,这样实际上我们就变成了位置1,这样就又可以继续往右滑动了。

    重复上面条件的判断,这样就实现了往右的循环,往左也是同样的道理。

    代码分析

    在onPageSelected里面做条件判断,在onPageScrollStateChanged里面做跳转。关键代码如下:

    初始化,首尾各增加一个item。

    1. // 增加第1个界面,实际上他显示的是最后一个界面  
    2. addTextView(POINT_LENGTH - 1);  
    3. // 增加实际显示的2、3、4界面  
    4. for (int i = 0; i < 3; i++) {  
    5. addTextView(i);  
    6. addPoint(i);  
    7. }  
    8. // 增加最后的第5个界面,实际上他显示的是第一个界面  
    9. addTextView(0);  

    条件判断:

    1. @Override  
    2. public void onPageSelected(int pPosition) {  
    3.     mIsChanged = true;  
    4.     if (pPosition > POINT_LENGTH) {  
    5.         mCurrentPagePosition = FIRST_ITEM_INDEX;  
    6.     } else if (pPosition < FIRST_ITEM_INDEX) {  
    7.         mCurrentPagePosition = POINT_LENGTH;  
    8.     } else {  
    9.         mCurrentPagePosition = pPosition;  
    10.     }  
    11.     Log.i(TAG,"当前的位置是"+mCurrentPagePosition);  
    12.     setCurrentDot(mCurrentPagePosition);  
    13. }  

    跳转:

    1. @Override  
    2. public void onPageScrollStateChanged(int pState) {  
    3.     if (ViewPager.SCROLL_STATE_IDLE == pState) {  
    4.         if (mIsChanged) {  
    5.             mIsChanged = false;  
    6.             mViewPager.setCurrentItem(mCurrentPagePosition, false);  
    7.         }  
    8.     }  
    9. }  

    完整的逻辑如下:

    1. package com.ahacool.circleviewpager;  
    2.   
    3. import java.util.ArrayList;  
    4.   
    5. import android.app.Activity;  
    6. import android.os.Bundle;  
    7. import android.support.v4.view.PagerAdapter;  
    8. import android.support.v4.view.ViewPager;  
    9. import android.support.v4.view.ViewPager.OnPageChangeListener;  
    10. import android.util.Log;  
    11. import android.view.Gravity;  
    12. import android.view.View;  
    13. import android.view.ViewGroup;  
    14. import android.widget.ImageView;  
    15. import android.widget.LinearLayout.LayoutParams;  
    16. import android.widget.TextView;  
    17.   
    18. /** 
    19.  * @ClassName MainActivity 
    20.  * @Description 循环滑动viewpager的一种方法,滑动很流畅。实现方法:在实际显示的界面头和尾分别增加一个界面。 
    21.  * @author Moto 
    22.  * @date 2014 2014-7-18 
    23.  *  
    24.  */  
    25. public class MainActivity extends Activity implements OnPageChangeListener {  
    26.   
    27.     private ViewPager mViewPager;  
    28.     private ViewGroup mPointViewGroup;  
    29.     private ArrayList<View> mViewPagerList;  
    30.     private boolean mIsChanged = false;  
    31.     private int mCurrentPagePosition = FIRST_ITEM_INDEX;  
    32.     private int mCurrentIndex;  
    33.     private static final int POINT_LENGTH = 3;  
    34.     private static final int FIRST_ITEM_INDEX = 1;  
    35.     private static final String TAG = "MOTO";  
    36.   
    37.     @Override  
    38.     protected void onCreate(Bundle savedInstanceState) {  
    39.         super.onCreate(savedInstanceState);  
    40.         setContentView(R.layout.activity_main);  
    41.         initUI();  
    42.     }  
    43.   
    44.     private void initUI() {  
    45.         mViewPager = (ViewPager) findViewById(R.id.viewpager);  
    46.         mPointViewGroup = (ViewGroup) findViewById(R.id.point_layout);  
    47.   
    48.         mViewPagerList = new ArrayList<View>();  
    49.         // 增加第1个界面,实际上他显示的是最后一个界面  
    50.         addTextView(POINT_LENGTH - 1);  
    51.         // 增加实际显示的2、3、4界面  
    52.         for (int i = 0; i < 3; i++) {  
    53.             addTextView(i);  
    54.             addPoint(i);  
    55.         }  
    56.         // 增加最后的第5个界面,实际上他显示的是第一个界面  
    57.         addTextView(0);  
    58.   
    59.         PagerAdapter pagerAdapter = new CustomPagerAdapter(mViewPagerList);  
    60.         mViewPager.setAdapter(pagerAdapter);  
    61.         mViewPager.setOnPageChangeListener(this);  
    62.         mViewPager.setCurrentItem(mCurrentPagePosition, false);  
    63.     }  
    64.   
    65.     private void addTextView(int pIndex) {  
    66.         TextView textview = new TextView(this);  
    67.         textview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));  
    68.         textview.setGravity(Gravity.CENTER);  
    69.         textview.setText("这是第" + (pIndex + 1) + "个页面");  
    70.         textview.setTextSize(50);  
    71.         mViewPagerList.add(textview);  
    72.     }  
    73.   
    74.     private void addPoint(int pIndex) {  
    75.         ImageView pointImageView = new ImageView(this);  
    76.         LayoutParams layoutParams = new LayoutParams(20, 20);  
    77.         layoutParams.setMargins(10, 0, 10, 0);  
    78.         pointImageView.setLayoutParams(layoutParams);  
    79.         pointImageView.setBackgroundResource(R.drawable.point_style);  
    80.         if (0 == pIndex) {  
    81.             pointImageView.setEnabled(false);  
    82.         }  
    83.         mPointViewGroup.addView(pointImageView);  
    84.     }  
    85.   
    86.     private void setCurrentDot(int positon) {  
    87.         // 界面实际显示的序号是第1, 2, 3。而点的序号应该是0, 1, 2.所以减1.  
    88.         positon = positon - 1;  
    89.         if (positon < 0 || positon > mViewPagerList.size() - 1 || mCurrentIndex == positon) {  
    90.             return;  
    91.         }  
    92.         mPointViewGroup.getChildAt(positon).setEnabled(false);  
    93.         mPointViewGroup.getChildAt(mCurrentIndex).setEnabled(true);  
    94.         mCurrentIndex = positon;  
    95.     }  
    96.   
    97.     @Override  
    98.     public void onPageScrollStateChanged(int pState) {  
    99.         if (ViewPager.SCROLL_STATE_IDLE == pState) {  
    100.             if (mIsChanged) {  
    101.                 mIsChanged = false;  
    102.                 mViewPager.setCurrentItem(mCurrentPagePosition, false);  
    103.             }  
    104.         }  
    105.     }  
    106.   
    107.     @Override  
    108.     public void onPageScrolled(int arg0, float arg1, int arg2) {  
    109.   
    110.     }  
    111.   
    112.     @Override  
    113.     public void onPageSelected(int pPosition) {  
    114.         mIsChanged = true;  
    115.         if (pPosition > POINT_LENGTH) {  
    116.             mCurrentPagePosition = FIRST_ITEM_INDEX;  
    117.         } else if (pPosition < FIRST_ITEM_INDEX) {  
    118.             mCurrentPagePosition = POINT_LENGTH;  
    119.         } else {  
    120.             mCurrentPagePosition = pPosition;  
    121.         }  
    122.         Log.i(TAG,"当前的位置是"+mCurrentPagePosition);  
    123.         setCurrentDot(mCurrentPagePosition);  
    124.     }  
    125.   
    126. }  

    源码下在地址:https://github.com/bird7310/Demos.git

    总结

    希望对大家有帮助,多提意见。近段时间项目很赶,很长时间没看书写博客了。赶项目赶得都麻木了,放松放松,偷偷懒,写写博客吧。

  • 相关阅读:
    uva10912 Simple Minded Hashing(DP)
    uva10401 Injured Queen Problem(DP)
    uva702 The Vindictive Coach(DP)
    忍者X4将采取自动开通vip,论坛充值淘宝自助购买均可。步骤如下
    C盘不够大,可以这样操作
    任务思维1
    PHP 获取指定日期的星期方法如下
    学学C#开发client,server,C/S架构的程序
    今天的主角就是protobuf-net
    关于忍者站群X4-小飞镖服务器配置帮助汇总。
  • 原文地址:https://www.cnblogs.com/dongweiq/p/3934422.html
Copyright © 2011-2022 走看看