Android之ViewPager学习笔记(MVP模式)

Android之ViewPager学习笔记(MVP模式)

  今天来分享分享我在android中学习的ViewPager控件,相信大家对这款控件非常熟悉也非常喜爱,在我们平时的微信中,滑动一个个的界面,就可以用我们的ViewPager来实现,由于内容不是很多,我今天就只用简单的MVP模式来写,不使用通用MVP模式了。
今天主要学习的内容有:
1. 如何实现简单的图片滑动
2. 如何实现手动无限轮播图片
3. 如何实现自动轮播图片

首先来看看简单的图片滑动:

具体结构如下:

这里写图片描述

view层:

MainActivity.java

public class MainActivity extends AppCompatActivity implements ViewInter<List<ImageView>>{

    //图片数据源
    private List<ImageView> mImages;
    //ViewPager控件
    private ViewPager mVPager;
    //适配器
    private MyAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mVPager = (ViewPager)findViewById(R.id.mVPager);
        new Presenter(this).load();
    }

    /**
     * 设置适配器数据
     * @param mImages 数据源
     */
    private void showAdapterData(List<ImageView> mImages){
        if(adapter == null){
            adapter = new MyAdapter(mImages);
            mVPager.setAdapter(adapter);
        }else{
            this.mImages.addAll(mImages);
            adapter.notifyDataSetChanged();
        }
    }

    /**
     * 获取Presenter层传回来的数据
     * @param mImages
     */
    @Override
    public void getData(List<ImageView> mImages) {
        this.mImages = mImages;
        showAdapterData(this.mImages);
    }
}

在MainActivity中,我们主要的任务就是通过请求presenter获取数据,然后presenter为我们回传我们需要的数据,然后拿到数据之后设置到自定的adapter中去,最后完成操作,数据就可以显示了

ViewInter.java

/**
* 将MainActivity中的所有功能都放入到这个接口中
*/
public interface ViewInter<T> {
    void getData(T t);
}

model层:

ModelInter.java

public interface ModelInter {
    /**
     * 处理数据
     * @param listener 回调接口
     */
    void getData(OnLoadLocalPicListener listener);


    interface OnLoadLocalPicListener{
        /**
         * 获取本地图片的方法
         */
        void getLocalPic();
    }
}

ModelImp.java

public class ModelImp implements ModelInter{
    /**
     * 负责处理数据,直接调用传过来的接口listener
     * @param listener 回调接口
     */
    @Override
    public void getData(OnLoadLocalPicListener listener) {
        listener.getLocalPic();
    }
}

presenter层:

Presenter.java

public class Presenter {
    ViewInter viewInter;
    ModelInter modelInter;

    public Presenter(ViewInter viewInter){
        this.viewInter = viewInter;
        modelInter = new ModelImp();
    }

    /**
     * 为view层处理请求
     */
    public void load(){
        /**
         * 请求调用model层的数据处理方法
         */
        modelInter.getData(new OnLoadLocalPic<>(viewInter,((MainActivity)viewInter).getApplicationContext()));
    }
}

callback包:

OnLoadLocalPic.java

public class OnLoadLocalPic<T extends ViewInter> implements ModelInter.OnLoadLocalPicListener {
    //ViewInter的子类Activity
    private T activity;
    //上下文
    private Context context;
    public OnLoadLocalPic(T view, Context context){
        this.activity = view;
        this.context = context;
        mImages = new ArrayList<>();
    }
    //获取图片数据集
    private List<ImageView> mImages;
    //本地的图片ID
    private int[] ids = {R.mipmap.one,R.mipmap.two,R.mipmap.three};
    @Override
    public void getLocalPic() {
        //设置数据
        for(int i = 0; i < ids.length; i++){

            //创建一个图片控件
            ImageView imageView = new ImageView(context);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setImageResource(ids[i]);
            mImages.add(imageView);
        }
        //回传给MainActivity
        activity.getData(mImages);
    }
}

上面的OnLoadLocalPic类,主要就是去实现ModelInter.OnLoadLocalPicListener接口中的getLocalPic方法,该方法主要的功能就是获取本地的图片,然后添加到集合中,回传给view层的MainActivity即可

下面看看简单的运行效果图:

这里写图片描述

上面的滑动效果没有录制好,所以将就一下吧。简单的来回滑动就实现了,很简单吧。

  1. 对于三张图片采取无限轮播的方式,这里我采用两种方式来实现无限轮播

实现前,先讲一个注意事项和PagerAdapter中的所有方法的运行过程,在我们用手指从右向左滑动屏幕时,首先执行移除当前不需要的图片(执行destroyItem方法,第一张和最后一张时,不需要执行该方法),再执行的是加载图片(执行instantiateItem方法)。默认来说,当前所加载的图片为当前显示页面的左右两张图片,除特殊情况下(第一张显示的,加载其右边的,最后一张,加载其左边的),而我们要了解的是,当我们用手指从左向右滑动时,首先执行的是先加载图片(先执行instantiateItem方法),然后再执行移除当前不需要的图片(执行destroyItem方法),在了解这个步奏后,下面开始实现代码:

方式1:将当前数据源修改一下,把List集合改成一个int[]类型,然后传过来当前本地的图片id,因为是无限滑动,所以我们要修改一下getCount方法的返回值。adapter中的instantiateItem方法代码如下

@Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }
@Override
    public Object instantiateItem(ViewGroup container, int position) {
        ImageView imageView = new ImageView(container.getContext());
        imageView.setScaleType(ImageView.ScaleType.FIT_XY);
        imageView.setImageResource(ids[position%ids.length]);
        container.addView(imageView);
        return imageView;
    }

每次滑动,都加载一个新的ImageView即可实现无限滑动,但是这种方式比较好内存,不推荐使用

方式2:添加一个标记,判断当前滑动的方向,代码如下:

@Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }
 @Override
    public Object instantiateItem(ViewGroup container, int position) {
        ImageView imageView = images.get(position % images.size());
        if(imageView.getParent() == null){
            Log.i("IT_Real", "instantiateItem: 加载");
            container.addView(imageView);
        }else{
            isBack = true;
            Log.i("IT_Real", "instantiateItem: 手动删除了");
            ((ViewGroup) imageView.getParent()).removeView(imageView);
            Log.i("IT_Real", "instantiateItem: 加载了");
            container.addView(imageView);
        }
        return imageView;
    }

     @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if(!isBack){
            Log.i("IT_Real", "destroyItem: 调用系统删除");
            container.removeView((View) object);
        }
        isBack = false;
    }

上的代码则可以节省内存的开销。
 
 
3. 最后就是实现自动无限轮播了

实现过程,只需要在主函数中添加一个handler消息机制即可,然后在设置完adapter之后,调用一次发送消息即可。代码如下:

在主函数中添加:

private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 100:
                    mVPager.setCurrentItem(mVPager.getCurrentItem() + 1);//每发送一个消息过来,就向后移动一次
                    sendEmptyMessageDelayed(100,1000);//每隔一秒发送一次请求
                    break;
            }
        }
    };

然后在onCreate中调用一次handler.sendEmptyMessageDelayed(100,1000);即可,注意该语句的顺序,要放在加载完数据语句new Presenter(this).load();之后

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值