Android 技术的回顾第三篇《轮播广告》



书到用时方恨少,技术到讲时才发现自己是真的会了、还是只是代码的搬运工。


现在APP首页上会有很多使用图片轮播的功能。同时,在包含底部菜单的情况使用图片轮播既是对手机内存的考验,也是对技术的一次摸底。

好了,废话不多说。

现在关于图片轮播,

网上的大多数方案是Thread+Handler 睡眠模式,那今天我们来了解的是一个定义好了通用方式下的单线程池+Handler模式

其中图片的加载我们使用的是Fresco ,当然你也可以试用一下Picasso或Glide

接下来,我们直接上代码

/**
 * 广告轮播 Created by zaric on 2016/5/17.
 */
public class Advert {
    private ScheduledExecutorService mScheduledExecutorService;
    private AdvertRunnable mAdvertRunnable;
    private int mPicNum = 0;
    private int mSize = 0;
    private ViewPager mViewPager;
    private Context mCtx;
    private ArrayList<SimpleDraweeView> mAdList;
    private ArrayList<String> mAdUrlList;
    private ArrayList<Integer> mAdLocalList;
    private ViewGroup mDotVg;
    private AdvertHandler mAdvertHandler;

    private boolean isStart = false;

    private boolean isLocal = false;

    /**
     * 装点点的ImageView数组
     */
    private ImageView[] mTips;

    public Advert(BaseActivity baseActivity) {
        this.mCtx = baseActivity;
        mViewPager = (ViewPager) baseActivity.findViewById(R.id.advertVp);
        mDotVg = (ViewGroup) baseActivity.findViewById(R.id.dotVg);
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int
                    positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                mAdvertHandler.setTipsSelected(position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    public Advert(View view) {
        this.mCtx = view.getContext();
        mViewPager = (ViewPager) view.findViewById(R.id.advertVp);
        mDotVg = (ViewGroup) view.findViewById(R.id.dotVg);
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int
                    positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                mAdvertHandler.setTipsSelected(position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    private void init() {
        mAdList = new ArrayList<>();
        if (mAdUrlList != null && mAdUrlList.size() > 0) {
            mSize = mAdUrlList.size();
            for (int i = 0; i < mSize; i++) {
                String path = mAdUrlList.get(i);
                if (TextUtils.isEmpty(path)) {
                    return;
                }
                SimpleDraweeView simpleDraweeView = new SimpleDraweeView(mCtx);
                simpleDraweeView.setScaleType(ImageView.ScaleType.FIT_XY);
                Uri uri = Uri.parse(path);
                simpleDraweeView.setImageURI(uri);
                mAdList.add(simpleDraweeView);
            }
        } else {
            if (mAdLocalList != null && mAdLocalList.size() > 0) {
                mSize = mAdLocalList.size();
                for (int i = 0; i < mSize; i++) {
                    int resId = mAdLocalList.get(i);
                    if (resId <= 0) {
                        return;
                    }
                    SimpleDraweeView simpleDraweeView = new SimpleDraweeView(mCtx);
                    simpleDraweeView.setScaleType(ImageView.ScaleType.FIT_XY);
                    simpleDraweeView.setBackgroundResource(resId);
                    mAdList.add(simpleDraweeView);
                }
            }
        }
        initTips();
        mScheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        mAdvertRunnable = new AdvertRunnable();
        mAdvertHandler = new AdvertHandler(mViewPager, mTips);
        AdvertAdapter advertAdapter = new AdvertAdapter(mAdList);
        mViewPager.setAdapter(advertAdapter);
        mViewPager.setCurrentItem(0);
    }

    /**
     * 初始化
     */
    public void initNet(ArrayList<String> adUrlList) {
        isLocal = false;
        mAdUrlList = adUrlList;
        init();

    }

    /**
     * 开始广告播放
     */
    public void startPlay() {
        // initialDelay 每隔多少秒执行一次
        // period       周期
        isStart = true;
        mScheduledExecutorService.scheduleAtFixedRate(mAdvertRunnable, 1, isLocal ? mAdLocalList
                        .size() : mAdUrlList.size(), TimeUnit.SECONDS);
    }

    /**
     * 按秒循环执行本地图片广告
     */
    public void initLocal(ArrayList<Integer> adLocalList) {
        isLocal = true;
        mAdLocalList = adLocalList;
        init();
    }

    public boolean isStart() {
        return isStart;
    }

    /**
     * 停止广告轮播
     */
    public void stopPlay() {
        if (mScheduledExecutorService != null) {
            isStart = false;
            mScheduledExecutorService.shutdownNow();
        }
    }

    public void destroy() {
        if (mAdList != null) {
            mAdList.clear();
        }
        if (mTips != null) {
            mTips = null;
        }
        if (mAdUrlList != null) {
            mAdUrlList.clear();
        }
    }

    /**
     * 图片轮播热点
     */
    private void initTips() {
        //将点点加入到ViewGroup        mTips = null;
        mDotVg.removeAllViews();
        mTips = new ImageView[mSize];
        for (int i = 0, length = mTips.length; i < length; i++) {
            ImageView imageView = new ImageView(mCtx);
            imageView.setLayoutParams(new ViewGroup.LayoutParams(20, 20));
            mTips[i] = imageView;
            if (i == 0) {
                mTips[i].setImageResource(R.drawable.dot_selected);
            } else {
                mTips[i].setImageResource(R.drawable.dot_unselected);
            }
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(new ViewGroup
                    .LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            layoutParams.leftMargin = 10;
            layoutParams.rightMargin = 10;
            mDotVg.addView(imageView, layoutParams);
        }
    }
    private class AdvertRunnable implements Runnable {

        @Override
        public void run() {
            mPicNum = (mPicNum + 1) % mSize;
            Message msg = mAdvertHandler.obtainMessage();
            msg.arg1 = mPicNum;
            msg.sendToTarget();
        }
    }

    private static class AdvertHandler extends Handler {
        private WeakReference<ViewPager> mWeakVp;
        private WeakReference<ImageView[]> mWeakIv;

        public AdvertHandler(ViewPager viewPager, ImageView[] tips) {
            mWeakVp = new WeakReference<>(viewPager);
            mWeakIv = new WeakReference<>(tips);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg == null) {
                return;
            }
            ViewPager mVp = mWeakVp.get();
            if (mVp == null) {
                return;
            }
            int picNum = msg.arg1;
            mVp.setCurrentItem(picNum);
            setTipsSelected(picNum);
        }

        /**
         * 设置选中的tip的背景
         *
         * @param selectItems 选中项
         */
        public void setTipsSelected(int selectItems) {
            ImageView[] mTips = mWeakIv.get();
            if (mTips == null) {
                return;
            }
            for (int i = 0, length = mTips.length; i < length; i++) {
                if (i == selectItems) {
                    mTips[i].setImageResource(R.drawable.dot_selected);
                } else {
                    mTips[i].setImageResource(R.drawable.dot_unselected);
                }
            }
        }
    }
}


/**
 * 广告轮播适配器
 * Created by zaric on 2016/5/17.
 */
public class AdvertAdapter extends PagerAdapter {
    private ArrayList<SimpleDraweeView> mList;
    public AdvertAdapter(ArrayList<SimpleDraweeView> mList){
        this.mList=mList;
    }
    @Override
    public int getCount() {
        return mList!=null&&mList.size()>0?mList.size():0;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view.equals(object);
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(mList.get(position));
        return mList.get(position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        try {
            container.removeView(mList.get(position));
        } catch (IndexOutOfBoundsException e) {
            e.printStackTrace();
        }
    }

    /**
     * 修改ViewPager自带缓存的BUG
     */
    private int mChildCount = 0;
    @Override
    public void notifyDataSetChanged() {
        mChildCount = getCount();
        super.notifyDataSetChanged();
    }

    @Override
    public int getItemPosition(Object object) {
        if ( mChildCount > 0) {
            mChildCount --;
            return POSITION_NONE;
        }
        return super.getItemPosition(object);
    }
}


下面是使用到的布局

<?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="wrap_content"
    >

    <android.support.v4.view.ViewPager
        android:id="@+id/advertVp"
        android:layout_width="match_parent"
        android:layout_height="130dp"
        android:fadingEdge="none"
        />
    <LinearLayout
        android:id="@+id/dotVg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/advertVp"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="5dp"
        android:gravity="center_vertical"
        android:orientation="horizontal"/>
</RelativeLayout>

那么接下来,我们就来来看看如何使用吧

首先,在需要广告轮播的布局页面中,添加


<include layout="@layout/layout_advert"/>

对应页面的代码中,Fragment  下


private Advert advert;
private ArrayList<Integer> localImg ;


localImg = new ArrayList<>();
localImg.add(R.drawable.bg_splash);
localImg.add(R.drawable.bg_splash);
localImg.add(R.drawable.bg_splash);
advert = new Advert(getView());
advert.initLocal(localImg);
advert.startPlay();

好了,到此结束了,至于原理和思想的话,欢迎大家一起讨论


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人生富有

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值