ViewPager+图片轮播

  • ViewPager是一个页面切换组件,可以往里面添加多个View
  • 需要一个适配器(Adapter)把多个View和Viewpager绑定(PageAdapter、FragmentAdapter、FragmentStateAdapter)
    PageAdapter和FragmentAdapter会缓存左边,当前,右边的三个页面,当处于最左边则只缓存当前和右边两个页面
    当有4个页面:
    若当前处于页面1,则会缓存1,2
    若当前处于页面2,则会缓存1,2,3
    适用页面少的情况下。
  • FragmentStateAdapter:只保存Fragment的状态,当对用户不可见时,Fragment被销毁。显示时则重新生成页面。适用页面多的情况下。

实现Runnable和继承Thread的区别
在这里插入图片描述

1. PagerAdapter的使用

重写的方法:
1.getCount():获得viewpager中有多少个view
2.destroyItem():移除一个给定位置的页面。
3.instantiateItem(): ①将给定位置的view添加到ViewGroup(容器)中,创建并显示出来 ②返回一个代表新增页面的Object(key),通常都是直接返回view本身就可以了,当然你也可以 自定义自己的key,但是key和每个view要一一对应的关系.( 渲染页面的函数)
4.isViewFromObject(): 判断instantiateItem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是 代表的同一个视图(即它俩是否是对应的,对应的表示同一个View),通常我们直接写 return view == object!

例子:
图片资源

public class Images {
    public static final int[] imageArrays=new int[]{R.drawable.bg1,R.drawable.bg2,R.drawable.bg3,
            R.drawable.bg4};

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v4.view.ViewPager>

</RelativeLayout>

子项View:viewpager_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/iv"
        android:layout_height="match_parent"
        android:layout_width="match_parent" />

</RelativeLayout>

自定义适配器

public class ViewPagerAdapter extends PagerAdapter {
    private Context context;
    private int[] datas;//图片资源
    private LayoutInflater layoutInflater;//布局加载器
    public ViewPagerAdapter(Context context,int[] datas){
        super();
        this.context=context;
        this.datas=datas;
        layoutInflater=LayoutInflater.from(context);
    }
    //ViewPager中View的个数
    @Override
    public int getCount() {
        return datas.length;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view==object;
    }
    //移除Item
    @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.inflate(R.layout.viewpager_item,null);//加载子项View
            ImageView iv= (ImageView) view.findViewById(R.id.iv);//获取子项View的子控件
            iv.setImageResource(datas[position]);//设置显示图片
            container.addView(view);//添加到ViewPager
            return view;
    }
}

MainActivity

public class MainActivity extends AppCompatActivity {
    private ViewPager vp;
    ViewPagerAdapter viewPagerAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        vp= (ViewPager) findViewById(R.id.vp);
        viewPagerAdapter=new ViewPagerAdapter(this,Images.imageArrays);
        vp.setAdapter(viewPagerAdapter);//为ViewPager添加适配器
    }
}

在渲染页面里还可以通过异步任务来实现

public class BitmapTask extends AsyncTask<Integer,Void,Bitmap> {
    private int res;
    private Context context;
    private ImageView iv;
    public BitmapTask(ImageView iv, Context context) {
        this.iv = iv;
        this.context = context;
    }

    @Override
    protected Bitmap doInBackground(Integer... params) {
        res=params[0];
        Bitmap bitmap= BitmapFactory.decodeResource(context.getResources(),res);
        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        iv.setImageBitmap(bitmap);
    }
}
@Override
    public Object instantiateItem(ViewGroup container, int position) {
            View view=layoutInflater.inflate(R.layout.viewpager_item,null);//加载子项View
            ImageView iv= (ImageView) view.findViewById(R.id.iv);//获取子项View的子控件
            //iv.setImageResource(datas[position]);//设置显示图片
            BitmapTask bitmapTask=new BitmapTask(iv,context);
            bitmapTask.execute(datas[position]);
            container.addView(view);//添加到ViewPager
            return view;
    }

实现轮播:上述切换只能切换到第四张,就不能再往右翻了。


第一种方式:欺骗适配器
修改如下

 @Override
    public int getCount() {
        return Integer.MAX_VALUE;
        //return datas.length;
    }

另外对position取余:position%datas.length

 bitmapTask.execute(datas[position%datas.length]);

但上述只能右翻,不能左翻,因为一开始是处于第0项,所以要设置初始显示的页面
在MainActivity中增加

vp.setCurrentItem(4*1000,true);//4表示的一共有4张照片轮播,这样左翻才能翻到第四张,true表示快速定位

所以综上,左翻和右翻都是有一定次数限定的。


第二种方式:构造数据源 :0-1-2-3 -》3-0-1-2-3-0,构造后的数据比原来的数据源多增加2个,当跳转到最后一个0时,把它切换到第一个0,对于3同理。
主要修改了MainActivity,还有ViewPagerAdapter也要修改回来

public class MainActivity extends AppCompatActivity {
    private ViewPager vp;
    ViewPagerAdapter viewPagerAdapter;
    private int[] datas=new int[Images.imageArrays.length+2];//比原来的数据多了2
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        vp= (ViewPager) findViewById(R.id.vp);
        viewPagerAdapter=new ViewPagerAdapter(this,datas);
        vp.setAdapter(viewPagerAdapter);
        vp.addOnPageChangeListener(new ViewPagerChandeListener());
        vp.setCurrentItem(1,true);
    }
//增加了该函数
    private void initData() {
        datas[0]=Images.imageArrays[Images.imageArrays.length-1];
        for(int i=0;i<Images.imageArrays.length;i++){
            datas[i+1]=Images.imageArrays[i];
        }
        datas[datas.length-1]=Images.imageArrays[0];
    }
    //增加了该ViewPager的监听
    class ViewPagerChandeListener implements ViewPager.OnPageChangeListener{
        @Override
        public void onPageSelected(int position) {
            if(position==0){
                vp.setCurrentItem(datas.length-2,true);
            }else if(position==datas.length-1){
                vp.setCurrentItem(1,true);
            }
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }


        @Override
        public void onPageScrollStateChanged(int state) {

        }
    }

}


实现自动轮播
修改MainActivity

public class MainActivity extends AppCompatActivity {
    private ViewPager vp;
    ViewPagerAdapter viewPagerAdapter;
    private int[] datas=new int[Images.imageArrays.length+2];

    //增加了这
    private ScheduledExecutorService scheduledExecutorService;
    private int CurrentIndex;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        vp= (ViewPager) findViewById(R.id.vp);
        viewPagerAdapter=new ViewPagerAdapter(this,datas);
        vp.setAdapter(viewPagerAdapter);
        vp.addOnPageChangeListener(new ViewPagerChandeListener());
        //增加了这
        CurrentIndex=1;

        vp.setCurrentItem(1,true);
    }
    //增加了这以下
    Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 1:
                    vp.setCurrentItem(CurrentIndex);
                    break;
            }
        }
    };
    @Override
    protected void onStart() {
        super.onStart();
        scheduledExecutorService= Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                CurrentIndex++;
                handler.sendEmptyMessage(1);
            }
        },10,10, TimeUnit.SECONDS);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if(scheduledExecutorService!=null)
            scheduledExecutorService.shutdown();

    }

    private void initData() {
        datas[0]=Images.imageArrays[Images.imageArrays.length-1];
        for(int i=0;i<Images.imageArrays.length;i++){
            datas[i+1]=Images.imageArrays[i];
        }
        datas[datas.length-1]=Images.imageArrays[0];
    }
    private class ViewPagerChandeListener implements ViewPager.OnPageChangeListener{
        @Override
        public void onPageSelected(int position) {
            //增加了这
            CurrentIndex=position;
            if(position==0){
                vp.setCurrentItem(datas.length-2,true);
            }else if(position==datas.length-1){
                vp.setCurrentItem(1,true);
            }
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }


        @Override
        public void onPageScrollStateChanged(int state) {

        }
    }

}

猜你喜欢

转载自blog.csdn.net/qq_42403295/article/details/88784839