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

    现在的情况

    不改变的源代码,什么时候ViewPager滑动到最后item的时候,他就无法再往右滑动;当ViewPager滑动到第一个item的时候,他也无法再往前滑动。

    (以上全是废话)

    设想

    我们能够这样想。当滑动到最后一个的时候,我们让他跳转到第一个,这样他就能够继续往后滑动了,这样就达到了我们想要的循环滑动。

    尽管功能上是循环了,可是实际显示的时候会在最后一个和第一个之间自己主动跳转。

    优化

    我们能够在原来的链表中首尾各添加一个假的item。用多余的两个item来作跳转的动作,这样就能够避免出现自己主动跳转的错误画面了。

    我们要显示的是以下ABC画面。位置各自是012.

     

    实际上,我们加入数据的时候,多加入了2个。

    在位置0加入了最后一个界面C,在位置4加入了第一个界面A

     

    当界面滑动到位置3的时候,他还能够往右滑动,这样给人的感觉就是循环的。但,当滑动到位置4的时候。他右边没有了,这样岂不是露馅了?所以,当滑动到位置4的时候。立马跳转到位置1

    由于他们是相同的数据,所以从显示效果是看不出跳转了的。这样实际上我们就变成了位置1,这样就又能够继续往右滑动了。

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

    代码分析

    onPageSelected里面做条件推断,在onPageScrollStateChanged里面做跳转。

    关键代码例如以下:

    初始化。首尾各添加一个item

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

    条件推断:

    	@Override
    	public void onPageSelected(int pPosition) {
    		mIsChanged = true;
    		if (pPosition > POINT_LENGTH) {
    			mCurrentPagePosition = FIRST_ITEM_INDEX;
    		} else if (pPosition < FIRST_ITEM_INDEX) {
    			mCurrentPagePosition = POINT_LENGTH;
    		} else {
    			mCurrentPagePosition = pPosition;
    		}
    		Log.i(TAG,"当前的位置是"+mCurrentPagePosition);
    		setCurrentDot(mCurrentPagePosition);
    	}

    跳转:

    	@Override
    	public void onPageScrollStateChanged(int pState) {
    		if (ViewPager.SCROLL_STATE_IDLE == pState) {
    			if (mIsChanged) {
    				mIsChanged = false;
    				mViewPager.setCurrentItem(mCurrentPagePosition, false);
    			}
    		}
    	}

    完整的逻辑例如以下:

    package com.ahacool.circleviewpager;
    
    import java.util.ArrayList;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.support.v4.view.PagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.support.v4.view.ViewPager.OnPageChangeListener;
    import android.util.Log;
    import android.view.Gravity;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.LinearLayout.LayoutParams;
    import android.widget.TextView;
    
    /**
     * @ClassName MainActivity
     * @Description 循环滑动viewpager的一种方法,滑动非常流畅。实现方法:在实际显示的界面头和尾分别添加一个界面。

    * @author Moto * @date 2014 2014-7-18 * */ public class MainActivity extends Activity implements OnPageChangeListener { private ViewPager mViewPager; private ViewGroup mPointViewGroup; private ArrayList<View> mViewPagerList; private boolean mIsChanged = false; private int mCurrentPagePosition = FIRST_ITEM_INDEX; private int mCurrentIndex; private static final int POINT_LENGTH = 3; private static final int FIRST_ITEM_INDEX = 1; private static final String TAG = "MOTO"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initUI(); } private void initUI() { mViewPager = (ViewPager) findViewById(R.id.viewpager); mPointViewGroup = (ViewGroup) findViewById(R.id.point_layout); mViewPagerList = new ArrayList<View>(); // 添加第1个界面,实际上他显示的是最后一个界面 addTextView(POINT_LENGTH - 1); // 添加实际显示的2、3、4界面 for (int i = 0; i < 3; i++) { addTextView(i); addPoint(i); } // 添加最后的第5个界面,实际上他显示的是第一个界面 addTextView(0); PagerAdapter pagerAdapter = new CustomPagerAdapter(mViewPagerList); mViewPager.setAdapter(pagerAdapter); mViewPager.setOnPageChangeListener(this); mViewPager.setCurrentItem(mCurrentPagePosition, false); } private void addTextView(int pIndex) { TextView textview = new TextView(this); textview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); textview.setGravity(Gravity.CENTER); textview.setText("这是第" + (pIndex + 1) + "个页面"); textview.setTextSize(50); mViewPagerList.add(textview); } private void addPoint(int pIndex) { ImageView pointImageView = new ImageView(this); LayoutParams layoutParams = new LayoutParams(20, 20); layoutParams.setMargins(10, 0, 10, 0); pointImageView.setLayoutParams(layoutParams); pointImageView.setBackgroundResource(R.drawable.point_style); if (0 == pIndex) { pointImageView.setEnabled(false); } mPointViewGroup.addView(pointImageView); } private void setCurrentDot(int positon) { // 界面实际显示的序号是第1, 2, 3。而点的序号应该是0, 1, 2.所以减1. positon = positon - 1; if (positon < 0 || positon > mViewPagerList.size() - 1 || mCurrentIndex == positon) { return; } mPointViewGroup.getChildAt(positon).setEnabled(false); mPointViewGroup.getChildAt(mCurrentIndex).setEnabled(true); mCurrentIndex = positon; } @Override public void onPageScrollStateChanged(int pState) { if (ViewPager.SCROLL_STATE_IDLE == pState) { if (mIsChanged) { mIsChanged = false; mViewPager.setCurrentItem(mCurrentPagePosition, false); } } } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int pPosition) { mIsChanged = true; if (pPosition > POINT_LENGTH) { mCurrentPagePosition = FIRST_ITEM_INDEX; } else if (pPosition < FIRST_ITEM_INDEX) { mCurrentPagePosition = POINT_LENGTH; } else { mCurrentPagePosition = pPosition; } Log.i(TAG,"当前的位置是"+mCurrentPagePosition); setCurrentDot(mCurrentPagePosition); } }

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

    总结

    希望对大家有帮助。多提意见。

    近段时间项目非常赶,非常长时间没看书写博客了。

    赶项目赶得都麻,放松。偷偷懒。写博客是。

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    重新整理 .net core 实践篇————防跨站脚本攻击[四十]
    重新整理 .net core 实践篇————重定向攻击[三十九]
    低数值精度推理和训练
    FinFET与芯片制程
    LLVM Backend技术
    安霸Ambarella CV系列芯片
    3D卷积,代码实现
    TVM darknet yolov3算子优化与量化代码的配置方法
    英特尔 QLC 3D NAND 数据存储
    Graph Representation 图神经网络
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4815698.html
Copyright © 2011-2022 走看看