Android-简单的轮播图控件BannerView

由于轮播图控件比较常用,就自己封装了一个简单的轮播图控件,废话不多说,直接上代码,使用的时候直接把下面这个类加入到工程就可以了


/**
 * Created by skyfly on 2017/9/13.
 * 通用的BannerView类
 */

public class BannerView extends LinearLayout implements ViewPager.OnPageChangeListener {
    private ViewPager mViewPager;
    private BannerAdapter mAdapter;
    private BannerViewListener mListener;
    private int mSelectedPageIndex = 0;
    private LinearLayout mIndicatorView;
    private BannerHandler mHandler;
    private boolean mIsScroll = false;
    private static int MSG_LOOP = 0x0001, LOOP_INTERVAL = 3000;


    private static class BannerHandler extends Handler {
        private WeakReference<BannerView> weakReference = null;

        public BannerHandler(BannerView bannerView) {
            super(Looper.getMainLooper());
            this.weakReference = new WeakReference<BannerView>(bannerView);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (this.weakReference == null) {
                return;
            }
            BannerView bannerView = this.weakReference.get();
            if (bannerView == null || bannerView.mViewPager == null || bannerView.mViewPager.getAdapter() == null || bannerView.mViewPager.getAdapter().getCount() <= 1) {
                return;
            }
            if (!bannerView.mIsScroll)
            {
                bannerView.mViewPager.setCurrentItem(bannerView.mSelectedPageIndex+1, true);
            }
        }
    }


    public interface BannerViewListener
    {
        void onShowImage(ImageView view, String imgUrl);
        void onItemClick(int position, String targetUrl, Object userData);
        View onCreateIndicatorView();
    }

    public BannerView(Context context) {
        this(context, null);
    }

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

    }

    @Override
    public void onPageSelected(int position) {
        selectIndicatorView(mAdapter.getDataPosition(mSelectedPageIndex), false);
        mSelectedPageIndex = position;
        selectIndicatorView(mAdapter.getDataPosition(mSelectedPageIndex), true);


    }

    @Override
    public void onPageScrollStateChanged(int state) {
        if (state == 1)
        {
            mIsScroll = true;
        }
        else if(state == 2)
        {
            mIsScroll = false;

            mHandler.removeCallbacksAndMessages(null);
            mHandler.sendEmptyMessageDelayed(MSG_LOOP, LOOP_INTERVAL);
        }
    }

    public BannerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BannerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initViews(context);
    }

    private void initViews(Context context) {
        // 动态创建对象
        RelativeLayout rl_banner = new RelativeLayout(context);
        rl_banner.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
        this.addView(rl_banner, MATCH_PARENT, MATCH_PARENT);

        mViewPager = new ViewPager(context);
        rl_banner.addView(mViewPager, MATCH_PARENT, MATCH_PARENT);
        mIndicatorView = new LinearLayout(context);
        mIndicatorView.setOrientation(HORIZONTAL);
        mIndicatorView.setGravity(CENTER);
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
        lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        lp.bottomMargin = (int) dip2px(context, 6);
        mIndicatorView.setLayoutParams(lp);
        rl_banner.addView(mIndicatorView);
        mViewPager.setAdapter(mAdapter = new BannerAdapter(this));
        mViewPager.addOnPageChangeListener(this);

        mHandler = new BannerHandler(this);
        // 启动循环
        mHandler.sendEmptyMessageDelayed(MSG_LOOP, LOOP_INTERVAL);
    }

    public void setBannerViewListener(BannerViewListener l)
    {
        mListener = l;
    }

    // 设置数据
    public void setBannerDatas(ArrayList<BannerInfo> data)
    {
        mAdapter.setBannerDatas(data);
        // 移除旧的
        mIndicatorView.removeAllViews();
        // 添加新的
        if (data.size() > 1) {
            for (int i = 0; i < data.size(); i++) {
                if (mListener != null)
                {
                    mIndicatorView.addView(mListener.onCreateIndicatorView());
                }
            }
        }
        if(data.size() > 1) {
            // 选中新的
            selectIndicatorView(mAdapter.getDataPosition(mSelectedPageIndex), true);
        }
    }

    private void selectIndicatorView(int index, boolean bSelected)
    {
        View v = mIndicatorView.getChildAt(index);
        if (v != null)
        {
            v.setSelected(bSelected);
        }
    }

    private void onItemClick()
    {
        if (mListener != null)
        {
            BannerInfo info = mAdapter.getItem(mSelectedPageIndex);
            if(info != null)
            {
                mListener.onItemClick(mAdapter.getDataPosition(mSelectedPageIndex), info.mTargetUrl, info.mUserData);
            }

        }
    }
    private void onShowImage(ImageView v, String url)
    {
        if (mListener != null)
        {
            mListener.onShowImage(v, url);
        }
    }


    private float dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (dpValue * scale + 0.5f);
    }


    public static class BannerInfo
    {
        public String mImgUrl;
        public String mTargetUrl;
        public Object mUserData;


        public BannerInfo(String img, String url)
        {
            this(img, url, null);
        }
        public BannerInfo(String img, String url, Object userData)
        {
            mImgUrl = img;
            mTargetUrl = url;
            mUserData = userData;
        }
    }

    private class BannerAdapter extends PagerAdapter implements View.OnClickListener
    {
        private ArrayList<BannerInfo> mData = new ArrayList<>();
        WeakReference<BannerView> mBannerViewWeakReference ;


        public BannerAdapter(BannerView v)
        {
            mBannerViewWeakReference  = new WeakReference<BannerView>(v) ;
        }

        public void setBannerDatas(ArrayList<BannerInfo> data)
        {
            mData = data;
            notifyDataSetChanged();
        }

        @Override
        public int getCount() {
            return mData.size() > 1 ? 100000000:mData.size();
        }

        @Override
        public boolean isViewFromObject(View v, Object o) {
            return v == o;
        }

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

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ImageView iv = new ImageView(container.getContext());
            iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
            iv.setOnClickListener(this);
            container.addView(iv, -1, -1);
            BannerInfo info = getItem(position);

            if ( mBannerViewWeakReference.get() != null ){
                mBannerViewWeakReference.get().onShowImage(iv, info.mImgUrl);
            }
            return iv;
        }

        public BannerInfo getItem(int position)
        {
            if (mData.size() < 1)
            {
                return null;
            }
            return mData.get(position%mData.size());
        }

        @Override
        public void onClick(View view) {
            Log.i("aaaa", "onClick");
            if ( mBannerViewWeakReference.get() != null ){
                mBannerViewWeakReference.get().onItemClick();
            }
        }

        @Override
        public int getItemPosition(Object object) {
            //return super.getItemPosition(object);
            return POSITION_NONE;
        }

        public int getDataPosition(int position)
        {
            return position%mData.size();
        }
    }
}


用法也比较简单,在XML中直接引用

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.penquanyun.datarecover.views.OrderTabFragment">

    <com.skyfly.controls.BannerView
        android:id="@+id/banner"
        android:layout_width="match_parent"
        android:layout_height="160dp" />

</FrameLayout>

初始化JAVA代码

BannerView bv = (BannerView) view.findViewById(R.id.banner);
bv.setBannerViewListener(new BannerView.BannerViewListener() {

    @Override
    public void onShowImage(ImageView view, String imgUrl) {
        BitmapUtils.getInstance().display(getContext(), view, imgUrl, R.drawable.img_banner_default);
    }

    @Override
    public void onItemClick(int position, String targetUrl, Object userData) {
    }

    @Override
    public View onCreateIndicatorView() {
        ImageView v = new ImageView(getContext());
        v.setPadding(10, 0, 0, 0);
        v.setImageResource(R.drawable.pager_indicator_selector);
        return v;
    }
});
ArrayList<BannerView.BannerInfo> testData = new ArrayList<>();
testData.add(new BannerView.BannerInfo("http://f11.baidu.com/it/u=918331178,1783361582&fm=72", ""));
testData.add(new BannerView.BannerInfo("http://f11.baidu.com/it/u=1678574154,1323011225&fm=72", ""));
testData.add(new BannerView.BannerInfo("http://f11.baidu.com/it/u=1678574154,1323011225&fm=72", ""));
testData.add(new BannerView.BannerInfo("http://f11.baidu.com/it/u=918331178,1783361582&fm=72", ""));
testData.add(new BannerView.BannerInfo("http://f11.baidu.com/it/u=1678574154,1323011225&fm=72", ""));
bv.setBannerDatas(testData);

onShowImage会在现实图片等时候调用,根据自己工程中使用的图片库自己实现

onCreateIndicatorView,在创建标签View的时候调用,这里可以自己随便定制

BannerInfo构造函数有多个实现,第一个参数是要显示的图片URL,第二个参数是点击后要跳转的URL,

pager_indicator_selector 是一个资源,这里给个参考

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
   <item android:state_selected="true" android:drawable="@drawable/icon_pager_indicator_selected" />
   <item android:drawable="@drawable/icon_pager_indicator_normal"/>
</selector>



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值