由于viewpager本身就可以左右滑动,但是如果设定的子选项比较少就达不到自动一直向着某个方向进行循环的特效,因此这里的核心只有两个方面 1.增大了默认的子选项,2.根据位置动态切换子选项的内容,让人觉得只有几个子选项,废话不多说,看代码!
1 先看activity的布局,很简单,相对布局上面一个viewpager 底部放置一个LinearLayout用来显示指示器
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:id="@+id/tip" android:layout_width="match_parent" android:layout_height="30dp" android:layout_alignParentBottom="true" android:background="#88000000" android:gravity="center" android:orientation="horizontal"></LinearLayout> </RelativeLayout>
2看activity代码,这个看来应该不难,没有删减都在这里,并且相关都注释了
package com.viewpagertest; import android.app.Activity; import android.os.Handler; import android.os.Message; import android.support.v4.view.*; import android.os.Bundle; import android.view.animation.AccelerateInterpolator; import android.widget.ImageView; import android.widget.LinearLayout; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; public class MainActivity extends Activity implements ViewPager.OnPageChangeListener { private ViewPager viewPager; private List<String> list;//放置图片路径 private List<ImageView> tiplist;//小圆点指示器 private int position;//手动切换时需要记录的位置 private long[] times = new long[2];//用于解决自动播放时间的问题,具体表现为:自动播放的时间是设死的,当我们刚手动翻页后由于自动滚动时间恰好也到了,造成连续翻页 private boolean scroll = true;//用于控制手动翻页后自动翻页问题 private LinearLayout tip; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); } private void initView(){ viewPager = (ViewPager) findViewById(R.id.viewpager); tip = (LinearLayout) findViewById(R.id.tip); viewPager.setOnPageChangeListener(this); } private void initData(){ //先装一些图片数据 list = new ArrayList<>(); list.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489570282189&di=f9b74624ee637571f01082ded85f130d&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2F201306%2F06%2F224844ywj2288uad25odju.jpg"); list.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489570282189&di=954965952df86aa00d1ccd70e090e77d&imgtype=0&src=http%3A%2F%2Fstatic01.coloros.com%2Fbbs%2Fdata%2Fattachment%2Fforum%2F201506%2F19%2F175554tisiqa1x33v3bz5r.png"); list.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489570282188&di=69646315a493f697bf4f86d87614b56d&imgtype=0&src=http%3A%2F%2Fattimg.dospy.com%2Fimg%2Fday_150423%2F20150423_877e17c8edf886bb463181ff38PGqgyP.jpg"); list.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489570282188&di=dcd14da79050da322eb6b59b681905a1&imgtype=0&src=http%3A%2F%2Fstatic01.coloros.com%2Fbbs%2Fdata%2Fattachment%2Fforum%2F201406%2F21%2F131944k8nmbbscw0iyzo5b.jpg"); list.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489570282187&di=0103cb2545fc50732674638c1ea133a1&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2F201311%2F18%2F0147375llb46o4jzp1l55n.jpg"); list.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489570282187&di=7ddd063f62a42be73ff902f655f0d66c&imgtype=0&src=http%3A%2F%2Fbbsdown10.cnmo.com%2Fattachments%2F201311%2F14%2F1127338wf8yy8ff8ffzuua.jpg"); list.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489570282187&di=faf8a83208733defb82a5da9e1c1ffb3&imgtype=0&src=http%3A%2F%2Fwww.mocuz.com%2Fdata%2Fattachments%2Fupload%2Fwallpaper%2F201503%2F20150331100907488.jpg"); list.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489570282185&di=eb44513f5b8334cc20da779b947873cf&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2F201311%2F10%2F1329459diz3617w5jw7w30.jpg"); //加载小圆点指示器 tiplist = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { ImageView imageView = new ImageView(this); imageView.setImageResource(R.mipmap.tip_false); imageView.setPadding(2, 2, 2, 2); tiplist.add(imageView); tip.addView(imageView); } //设置首个小圆点自黑 tiplist.get(0).setImageResource(R.mipmap.tip_true); //适配器初始化 MPagerAdapter adapter = new MPagerAdapter(this, list); viewPager.setAdapter(adapter); //滚动时界面滑动的速度 setViewPagerScrollSpeed(); //进入后viewpager显示不是第一个子选项,这样可以直接右滑 change(100 * list.size()); //滚动开始 timeScroll(); //记录滚动开始的时间 times[0] = System.currentTimeMillis(); } /** * 这里采用thread 和handler做计时控制 */ private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); change(position); } }; /** * 控制viewpager顺序滑动,轮播 */ private void timeScroll() { new Thread() { @Override public void run() { super.run(); while (true) { try { long time = 2000; Thread.sleep(time); //如果时间小于自动滚动时间,这里控制不再自动滚动 if (scroll) { handler.sendEmptyMessage(1); } else { scroll = true; } } catch (Exception e) { } } } }.start(); } /** * 控制viewpager的滑动速度, */ FixedSpeedScroller mScroller = null; private void setViewPagerScrollSpeed() { try { Field field = ViewPager.class.getDeclaredField("mScroller"); field.setAccessible(true); mScroller = new FixedSpeedScroller(viewPager.getContext(), new AccelerateInterpolator()); field.set(viewPager, mScroller); } catch (Exception e) { } } /** * 手动切换viewpager使用 * * @param position 当前界面位置 */ private void change(int position) { if (position < 10000) { viewPager.setCurrentItem(position + 1, true); } else { viewPager.setCurrentItem(0, false); } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { this.position = position; //手动切换或者自动切换,记录一个时间,用于和上次切换时间做对比,如果小于轮播时间,则说明手动切换了,这里对scroll=false; times[1] = System.currentTimeMillis(); if (times[1] - times[0] < 2000) { scroll = false; } else { scroll = true; } times[0] = times[1]; //指示器控制 for (ImageView v : tiplist) { v.setImageResource(R.mipmap.tip_false); } tiplist.get(position % list.size()).setImageResource(R.mipmap.tip_true); } @Override public void onPageScrollStateChanged(int state) { } }3 看适配器代码,这里要注意getcount 方法设置的子选项比较大,另一个instantiateItem方法中子选项变换后动态切换图片路径,保证子选项不管怎么变,但是图片的显示顺序不变
package com.viewpagertest; import android.content.Context; import android.support.v4.view.PagerAdapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import com.squareup.picasso.Picasso; import java.util.List; /** * Created by on 2017/3/15. */ public class MPagerAdapter extends PagerAdapter { /** * 默认设置10000个界面,来达到可以左右滑动的效果 */ final int PAGER_SIZE = 10000; private List<String> list; Context context; public MPagerAdapter(Context context, List<String> list) { this.list = list; this.context = context; } @Override public int getCount() { return PAGER_SIZE; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } @Override public Object instantiateItem(ViewGroup container, int position) { View view = LayoutInflater.from(context).inflate(R.layout.item, container,false); ImageView imageView = (ImageView) view.findViewById(R.id.image); Picasso.with(context).load(list.get(position%list.size())).into(imageView); container.addView(view); return view; } }4 这个不太相关,就是控制viewpager滚动速度的,也贴出来了
package com.viewpagertest; import android.content.Context; import android.view.animation.Interpolator; import android.widget.Scroller; /** * Created by on 2017/2/14. * 控制viewpager滑动速度 */ public class FixedSpeedScroller extends Scroller { private int mDuration =300; public FixedSpeedScroller(Context context) { super(context); } public FixedSpeedScroller(Context context, Interpolator interpolator) { super(context, interpolator); } public FixedSpeedScroller(Context context, Interpolator interpolator, boolean flywheel) { super(context, interpolator, flywheel); } @Override public void startScroll(int startX, int startY, int dx, int dy, int duration) { super.startScroll(startX, startY, dx, dy, mDuration); } @Override public void startScroll(int startX, int startY, int dx, int dy) { super.startScroll(startX, startY, dx, dy, mDuration); } public void setmDuration(int mDuration) { this.mDuration = mDuration; } }
再啰嗦下,1具体思想就是让子选项的数量很大,2在适配器的instantiateItem方法中动态切换要显示的内容,3在启动时用viewPager.setCurrentItem(position + 1, true)设置前面有一定的子选项数,这样刚开始就可以向右滑动,就啰嗦这么多!效果图如下