Android 封装自定义无限轮播banner之体验装饰模式

现在基本每个资讯类应用都会使用到banner来无限轮播,现在项目中使用别人封装的ViewPager总会遇到不可预知的问题,修改起来也十分麻烦,于是决定自己封装一个,在使用适配器的时候遇到一个问题,就是虽然是ViewPage的PageAdapter逻辑部分肯定是要留给使用者去写的,但是adapter给他写了之后,我还要在里面扩展上无限轮播的功能,例如getCount()里我要给它加上一个2。所以这里就要使用上装饰者模式来扩展一下了。

简单介绍一下装饰模式
(1)抽象组件:定义一个抽象接口,来规范准备附加功能的类

(2)具体组件:将要被附加功能的类,实现抽象构件角色接口

(3)抽象装饰者:持有对具体构件角色的引用并定义与抽象构件角色一致的接口

(4)具体装饰:实现抽象装饰者角色,负责对具体构件添加额外功能。

(引用自https://www.cnblogs.com/chenxing818/p/4705919.html)。
里面有具体的代码示例来讲解装饰模式,通俗易懂。

实际的使用:

首先写一个正常的pageAdapter

class ArticleListBannerAdapter extends PagerAdapter {
    private List<Article> data;
    private Context context;

    ArticleListBannerAdapter(Context context) {
        data = new ArrayList<>();
        this.context = context;
    }

    void addAll(List<Article> data) {
        this.data = data;
    }

    void clear(){
        data.clear();
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        //业务逻辑。。。。。
        ItemHeadHomeBinding itemHeadHomeBinding;
        container.addView(itemHeadHomeBinding.getRoot());
        return itemHeadHomeBinding.getRoot();
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }
}

然后就是自定义ViewPager中新建一个包装类:

 private class BannerAdapterWrapper extends PagerAdapter {
        private PagerAdapter pagerAdapter;

        public BannerAdapterWrapper(PagerAdapter pagerAdapter) {
            this.pagerAdapter = pagerAdapter;
        }

        @Override
        public int getCount() {
            return pagerAdapter.getCount() > 1 ? pagerAdapter.getCount() + 2 : pagerAdapter.getCount();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view.equals(object);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            return pagerAdapter.instantiateItem(container, bannerToAdapterPosition(position));
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            pagerAdapter.destroyItem(container, position, object);
        }

        /**
         * position 转换
         *
         * @param position
         * @return
         */
        public int bannerToAdapterPosition(int position) {
            int adapterCount = adapter.getCount();
            if (adapterCount <= 1) return 0;
            int adapterPosition = (position - 1) % adapterCount;
            if (adapterPosition < 0) adapterPosition += adapterCount;
            return adapterPosition;
        }

        public int toWrapperPosition(int position) {
            return position + 1;
        }
    }

两个Position方法是adapter和adapterWrapper的position不一致之前的相互转换。

然后重写setAdatper方法

    private BannerAdapterWrapper bannerAdapterWrapper;
    private PagerAdapter adapter;
    private BannerAdapterWrapper bannerAdapterWrapper;
    private PagerAdapter adapter;
    @Override
    public void setAdapter(PagerAdapter adapter) {
        this.adapter = adapter;
        this.adapter.registerDataSetObserver(new BannerPagerObserver());
        bannerAdapterWrapper = new BannerAdapterWrapper(adapter);
        super.setAdapter(bannerAdapterWrapper);
        addOnPageChangeListener(new BannerPageChangeListener());
    }

注意:
this.adapter.registerDataSetObserver(new BannerPagerObserver());是为了让原来的adapter数据刷新的时候能让adapterWrapper同步刷新设置的监听。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值