Android基础控件——Banner轮播图的无限循环轮播功能、手动滑动功能

来源:互联网 发布:linux tail grep 结合 编辑:程序博客网 时间:2024/04/29 19:14

Banner轮播图的无限循环轮播功能、手动滑动功能


轮播图实现:(假如5张图轮播)

1、在List中存好这5张图,传到ViewPager的Adapter中,相当于5张图片横铺在ViewPager控件中。

2、设置ViewPager一开始的起始位置为5*1000=5000,并用seletedBanner记录该位置。

3、在PagerAdapter中将其getCount方法返回Integer的最大值,让它向左向右滑都不会越界。

4、在PagerAdapter中必须对当前位置%5(由于5张图,%5结果在0-4之间,刚好是图片集合的下标,如5002%5=2,就是List[2]中的对象)

5、ViewPager监听滚动事件,用seletedBanner记录新位置。

6、在onResume中开始轮播。

圆点实现:

1、在一个水平的布局中添加5个圆点View对象,并存入一个List中。

2、遍历圆点List,在ViewPager滚动回调中判断seletedBanner(当前位置)%5,则该得到的值为选中圆点,其他为未选中圆点。

其效果图:



实现步骤


1、自定义RelativeLayout,编写固定的构造方法

public class MyBannerView extends RelativeLayout implements View.OnTouchListener, ViewPager.OnPageChangeListener {    public MyBannerView(Context context) {        this(context, null);    }    public MyBannerView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MyBannerView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        //初始化工作        initBannerViews(context, attrs, defStyleAttr);    }}

2、声明需要用到的变量

    //轮播图控件    private ViewPager targetVp;    //轮播图集合    private ArrayList<View> bannerList;    //指示器图集合    private ArrayList<View> indicationList;    //上下文    private Context context;    //当前轮播图位置    private int selectedBanner;    //提示轮播    private final static int BANNER_CHANGE = 0;    //是否为网络图片加载,作用是:如果是网络图片加载就不滚动轮播图,让用户自己手动滑动轮播图    boolean isNetImg = false;


3、初始化用到的组件

    private void initBannerViews(Context context, AttributeSet attrs, int defStyleAttr) {        this.context = context;        //初始化ViewPager        targetVp = new ViewPager(context);        targetVp.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));        targetVp.setOnTouchListener(this);        targetVp.setOnPageChangeListener(this);        //添加到View中        addView(targetVp);    }

4、提供方法加载图片和指示器


这里有两个方法,加载本地图片和加载网络图片,加载网络图片用到Glide第三方框架,Glide的学习可以查看我的博客

    /**     * 在本地Drawable中加载轮播图     *     * @param activity     * @param img_urls 轮播图drawable的ID     */    public void initShowImageForLocal(Activity activity, int[] img_urls) {        //指示器布局        LinearLayout ly_indication = new LinearLayout(activity);        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);        //指示器边距        params.bottomMargin = 15;        //指示器位置        params.addRule(ALIGN_PARENT_BOTTOM);        params.addRule(CENTER_HORIZONTAL);        //添加到View中        addView(ly_indication, params);        //图片集合和指示器集合        bannerList = new ArrayList<View>();        indicationList = new ArrayList<View>();        for (int i = 0; i < img_urls.length; i++) {            //初始化图片            ImageView iv = new ImageView(activity);            iv.setScaleType(ImageView.ScaleType.FIT_XY);            iv.setBackgroundResource(img_urls[i]);            bannerList.add(iv);            //初始化指示器            ImageView iv2 = new ImageView(activity);            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);            lp.setMargins(8, 0, 0, 0);            iv2.setLayoutParams(lp);            //初始化指示器默认为第一张高亮            if (i == 0) {                iv2.setBackgroundResource(R.drawable.home_top_ic_point_on);            } else {                iv2.setBackgroundResource(R.drawable.home_top_ic_point_off);            }            indicationList.add(iv2);            //添加到圆点布局            ly_indication.addView(iv2);        }        //初始化轮播Adapter        HomeBannerAdapter bannerAdapter = new HomeBannerAdapter(bannerList, activity);        targetVp.setAdapter(bannerAdapter);        //初始化当前位置        targetVp.setCurrentItem(bannerList.size() * 1000);        //当前position        selectedBanner = bannerList.size() * 1000;    }    /**     * 通过网络Url加载轮播图     *     * @param activity     * @param img_urls 网络图片的URL     */    public void initShowImageForNet(Activity activity, List<String> img_urls) {        //标识是网络加载        isNetImg = true;        //指示器布局        LinearLayout ly_indication = new LinearLayout(activity);        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);        // 指示器边距        params.bottomMargin = 15;        //指示器位置        params.addRule(ALIGN_PARENT_BOTTOM);        params.addRule(CENTER_HORIZONTAL);        //添加到View中        addView(ly_indication, params);        //图片集合和指示器集合        bannerList = new ArrayList<View>();        indicationList = new ArrayList<View>();        for (int i = 0; i < img_urls.size(); i++) {            //初始化图片            ImageView iv = new ImageView(activity);            iv.setScaleType(ImageView.ScaleType.FIT_XY);            GlideUtils.setImageView(context, img_urls.get(i), iv);            bannerList.add(iv);            //初始化指示器            ImageView iv2 = new ImageView(activity);            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);            lp.setMargins(8, 0, 0, 0);            iv2.setLayoutParams(lp);            if (i == 0) {                iv2.setBackgroundResource(R.drawable.home_top_ic_point_on);            } else {                iv2.setBackgroundResource(R.drawable.home_top_ic_point_off);            }            indicationList.add(iv2);            //添加到圆点布局            ly_indication.addView(iv2);        }        //初始化轮播数据        HomeBannerAdapter bannerAdapter = new HomeBannerAdapter(bannerList, activity);        targetVp.setAdapter(bannerAdapter);        //初始化当前位置        targetVp.setCurrentItem(bannerList.size() * 1000);        //当前position        selectedBanner = bannerList.size() * 1000;    }


5、实现监听事件

    @Override    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {    }    @Override    public void onPageSelected(int position) {        //改变当前位置指针        selectedBanner = position;        //改变指示器变化        bannerPointLight(position % indicationList.size());    }    @Override    public void onPageScrollStateChanged(int state) {    }    @Override    public boolean onTouch(View v, MotionEvent event) {        //如果是网络加载则没必要监听        if (isNetImg) {            return false;        }        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                //结束轮播                mHandler.removeCallbacksAndMessages(null);                break;            case MotionEvent.ACTION_UP:                //开启轮播                mHandler.sendEmptyMessageDelayed(BANNER_CHANGE, 3000);                break;            case MotionEvent.ACTION_CANCEL:                //开启轮播                mHandler.sendEmptyMessageDelayed(BANNER_CHANGE, 3000);                break;        }        return false;    }


6、提供开启轮播和结束轮播的方法

    /**     * 开始轮播     */    public void startBanner() {        //开启轮播        mHandler.sendEmptyMessageDelayed(BANNER_CHANGE, 3000);    }    /**     * 结束轮播     */    public void endBanner() {        //结束轮播        mHandler.removeCallbacksAndMessages(null);    }


7、处理轮播

    /**     * 消息处理器     */    private Handler mHandler = new Handler() {        public void handleMessage(Message msg) {            switch (msg.what) {                case BANNER_CHANGE:                    //形成轮播循环                    targetVp.setCurrentItem(selectedBanner + 1);                    mHandler.sendEmptyMessageDelayed(BANNER_CHANGE, 3000);                    break;            }        }    };


8、编写HomeBannerAdapter

    /**     * 适配器     */    public class HomeBannerAdapter extends PagerAdapter {        private List<View> views;        private Context context;        public HomeBannerAdapter(List<View> views, Context context) {            this.context = context;            this.views = views;        }        public Object instantiateItem(View container, int position) {            final int currentItem = position % views.size();            ((ViewPager) container).addView(views.get(currentItem));            return views.get(currentItem);        }        public void destroyItem(View container, int position, Object object) {            ((ViewPager) container).removeView((View) object);        }        public int getCount() {            return Integer.MAX_VALUE;        }        public boolean isViewFromObject(View arg0, Object arg1) {            return (arg0 == arg1);        }    }


9、编写两个圆点的xml文件


① 红点

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="oval">    <solid android:color="#FF5000"/>    <stroke        android:width="0.1dp"        android:color="#8888" />    <size        android:width="6dp"        android:height="6dp" /></shape>


② 灰点

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="oval">    <solid android:color="#88ffffff"/>    <stroke        android:width="0.1dp"        android:color="#8888" />    <size        android:width="6dp"        android:height="6dp" /></shape>

10、接着就可以在Acitivity中使用我们的自定义的BannerView


① 编写布局文件,使用我们的自定义BannerView

        <com.handsome.didi.View.MyBannerView                android:id="@+id/vp_banner"                android:layout_width="match_parent"                android:layout_height="120dp" />


② 在代码中找到对应ID控件,并且初始化

vp_banner = findView(R.id.vp_banner);vp_banner.initShowImageForNet(getActivity(), new ArrayList<String>{"","","",""});


③ 开启轮播和停止轮播

    @Override    public void onResume() {        super.onResume();        //开始轮播        vp_banner.startBanner();    }    @Override    public void onPause() {        super.onPause();        //停止轮播        vp_banner.endBanner();    }

源码下载


源码下载说明

1、网络图片加载要用到第三库Glide

2、网络加载默认是不会自动轮播的,如果需要自动轮播需要将if(isNetImg){return false};去掉







1 0
原创粉丝点击