Android 自动广告轮播图

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012162503/article/details/51385141

近来项目忙完了,觉得自己的自动广告轮播 蛮不错的 ,所以分享出来。先说说他的功能,第一能够实现自动轮播 图片 ,第二可以修改自动更换广告条的小点默认是圆形的 可以修改为小的正方向 ,同时 还可以修改 原点所在的位置 居中 居左 居 右,以及颜色改变等等。
1.代码如下:
/**
* Created by xiaomo on 2015/8/9.
*/
public class BannerLayout extends RelativeLayout {

private ViewPager pager;
//指示器容器
private LinearLayout indicatorContainer;

private Drawable unSelectedDrawable;
private Drawable selectedDrawable;

private int WHAT_AUTO_PLAY = 1000;

private boolean isAutoPlay = true;

private int itemCount;

/**点选中的颜色**/
private int selectedIndicatorColor = 0xffff0000;
/**未选中的颜色**/
private int unSelectedIndicatorColor = 0x88888888;
/**点的类型 、oval(圆点)、rect(方形)**/
private Shape indicatorShape = Shape.oval;
/**选中小圆点高**/
private int selectedIndicatorHeight = 6;
/**选中小圆点宽**/
private int selectedIndicatorWidth = 6;
/**未选中小圆点高**/
private int unSelectedIndicatorHeight = 6;
/**未选中小圆点宽**/
private int unSelectedIndicatorWidth = 6;
/**scroll的持续时间**/
private Position indicatorPosition = Position.centerBottom;
/**滑动的时间*/
private int autoPlayDuration = 3000;
/**scroll的持续时间**/
private int scrollDuration = 1100;
/**滑动小圆点间距**/
private int indicatorSpace = 3;
/**滑动小圆点边缘的间距**/
private int indicatorMargin = 10;

private enum Shape {
    rect, oval
}

private enum Position {
    centerBottom,
    rightBottom,
    leftBottom,
    centerTop,
    rightTop,
    leftTop
}

private OnBannerItemClickListener onBannerItemClickListener;

private Handler handler = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        if (msg.what == WHAT_AUTO_PLAY) {
            if(null == pager){
                return false;
            }
            pager.setCurrentItem(pager.getCurrentItem() + 1, true);
            handler.sendEmptyMessageDelayed(WHAT_AUTO_PLAY, autoPlayDuration);
        }
        return false;
    }
});

public BannerLayout(Context context) {
    super(context);
    init(null, 0);
}

public BannerLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(attrs, 0);
}

public BannerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(attrs, defStyleAttr);
}

private void init(AttributeSet attrs, int defStyle) {

    TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.BannerLayoutStyle, defStyle, 0);
    selectedIndicatorColor = array.getColor(R.styleable.BannerLayoutStyle_selectedIndicatorColor, selectedIndicatorColor);
    unSelectedIndicatorColor = array.getColor(R.styleable.BannerLayoutStyle_unSelectedIndicatorColor, unSelectedIndicatorColor);

    int shape = array.getInt(R.styleable.BannerLayoutStyle_indicatorShape, Shape.oval.ordinal());
    for (Shape shape1 : Shape.values()) {
        if (shape1.ordinal() == shape) {
            indicatorShape = shape1;
            break;
        }
    }
    selectedIndicatorHeight = (int) array.getDimension(R.styleable.BannerLayoutStyle_selectedIndicatorHeight, selectedIndicatorHeight);
    selectedIndicatorWidth = (int) array.getDimension(R.styleable.BannerLayoutStyle_selectedIndicatorWidth, selectedIndicatorWidth);
    unSelectedIndicatorHeight = (int) array.getDimension(R.styleable.BannerLayoutStyle_unSelectedIndicatorHeight, unSelectedIndicatorHeight);
    unSelectedIndicatorWidth = (int) array.getDimension(R.styleable.BannerLayoutStyle_unSelectedIndicatorWidth, unSelectedIndicatorWidth);

    int position = array.getInt(R.styleable.BannerLayoutStyle_indicatorPosition, Position.centerBottom.ordinal());
    for (Position position1 : Position.values()) {
        if (position == position1.ordinal()) {
            indicatorPosition = position1;
        }
    }
    indicatorSpace = (int) array.getDimension(R.styleable.BannerLayoutStyle_indicatorSpace, indicatorSpace);
    indicatorMargin = (int) array.getDimension(R.styleable.BannerLayoutStyle_indicatorMargin, indicatorMargin);
    autoPlayDuration = array.getInt(R.styleable.BannerLayoutStyle_autoPlayDuration, autoPlayDuration);
    scrollDuration = array.getInt(R.styleable.BannerLayoutStyle_scrollDuration, scrollDuration);
    isAutoPlay = array.getBoolean(R.styleable.BannerLayoutStyle_isAutoPlay, isAutoPlay);
    array.recycle();

    //绘制未选中状态图形
    LayerDrawable unSelectedLayerDrawable;
    LayerDrawable selectedLayerDrawable;
    GradientDrawable unSelectedGradientDrawable;
    unSelectedGradientDrawable = new GradientDrawable();

    //绘制选中状态图形
    GradientDrawable selectedGradientDrawable;
    selectedGradientDrawable = new GradientDrawable();
    switch (indicatorShape) {
        case rect:
            unSelectedGradientDrawable.setShape(GradientDrawable.RECTANGLE);
            selectedGradientDrawable.setShape(GradientDrawable.RECTANGLE);
            break;
        case oval:
            unSelectedGradientDrawable.setShape(GradientDrawable.OVAL);
            selectedGradientDrawable.setShape(GradientDrawable.OVAL);
            break;
    }
    unSelectedGradientDrawable.setColor(unSelectedIndicatorColor);
    unSelectedGradientDrawable.setSize(unSelectedIndicatorWidth, unSelectedIndicatorHeight);
    unSelectedLayerDrawable = new LayerDrawable(new Drawable[]{unSelectedGradientDrawable});
    unSelectedDrawable = unSelectedLayerDrawable;

    selectedGradientDrawable.setColor(selectedIndicatorColor);
    selectedGradientDrawable.setSize(selectedIndicatorWidth, selectedIndicatorHeight);
    selectedLayerDrawable = new LayerDrawable(new Drawable[]{selectedGradientDrawable});
    selectedDrawable = selectedLayerDrawable;

}

//添加本地图片路径
public void setViewRes(List<Integer> viewRes) {
    List<View> views = new ArrayList<View>();
    itemCount = viewRes.size();
    //主要是解决当item为小于3个的时候滑动有问题,这里将其拼凑成3个以上
    if (itemCount < 1) {//当item个数0
        throw new IllegalStateException("item count not equal zero");
    } else if (itemCount < 2) {//当item个数为1
        views.add(getImageView(viewRes.get(0), 0));
        views.add(getImageView(viewRes.get(0), 0));
        views.add(getImageView(viewRes.get(0), 0));
    } else if (itemCount < 3) {//当item个数为2
        views.add(getImageView(viewRes.get(0), 0));
        views.add(getImageView(viewRes.get(1), 1));
        views.add(getImageView(viewRes.get(0), 0));
        views.add(getImageView(viewRes.get(1), 1));

    } else {
        for (int i = 0; i < viewRes.size(); i++) {
            views.add(getImageView(viewRes.get(i), i));
        }
    }
    setViews(views);
}

*private SimpleDraweeView  getImageView (Integer res, final int position) {
    SimpleDraweeView  imageView = new SimpleDraweeView (getContext());
    imageView.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (onBannerItemClickListener != null) {
                onBannerItemClickListener.onItemClick(position);
            }
        }
    });*
    imageView.setHierarchy(AppContext.setHierarchy(imageView,R.mipmap.icon_notad));
    AppContext.loadPicture(imageView,res+"");
    return imageView;
}


//添加网络图片路径
public void setViewUrls(List<String> urls) {
    List<View> views = new ArrayList<View>();
    itemCount = urls.size();
    //主要是解决当item为小于3个的时候滑动有问题,这里将其拼凑成3个以上
    if (itemCount < 1) {//当item个数0
        throw new IllegalStateException("item count not equal zero");
    } else if (itemCount < 2) { //当item个数为1
        views.add(getImageView(urls.get(0), 0));
        views.add(getImageView(urls.get(0), 0));
        views.add(getImageView(urls.get(0), 0));
    } else if (itemCount < 3) {//当item个数为2
        views.add(getImageView(urls.get(0), 0));
        views.add(getImageView(urls.get(1), 1));
        views.add(getImageView(urls.get(0), 0));
        views.add(getImageView(urls.get(1), 1));
    } else {
        for (int i = 0; i < urls.size(); i++) {
            views.add(getImageView(urls.get(i), i));
        }
    }
    setViews(views);
}

private SimpleDraweeView getImageView(String url, final int position) {
    SimpleDraweeView imageView = new SimpleDraweeView(getContext());
    imageView.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (onBannerItemClickListener != null) {
                onBannerItemClickListener.onItemClick(position);
            }
        }
    });
    imageView.setHierarchy(AppContext.setHierarchy(imageView, R.mipmap.icon_notad));
    AppContext.loadPicture(imageView, url + "");
    return imageView;
}

//添加任意View视图
private void setViews(final List<View> views) {
    //初始化pager
    pager = new ViewPager(getContext());
    //添加viewpager到SliderLayout
    addView(pager);
    setSliderTransformDuration(scrollDuration);
    //初始化indicatorContainer
    indicatorContainer = new LinearLayout(getContext());
    indicatorContainer.setGravity(Gravity.CENTER_VERTICAL);
    LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

    switch (indicatorPosition) {
        case centerBottom:
            params.addRule(RelativeLayout.CENTER_HORIZONTAL);
            params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            break;
        case centerTop:
            params.addRule(RelativeLayout.CENTER_HORIZONTAL);
            params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
            break;
        case leftBottom:
            params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            break;
        case leftTop:
            params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
            break;
        case rightBottom:
            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            break;
        case rightTop:
            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
            break;
    }
    //设置margin
    params.setMargins(indicatorMargin, indicatorMargin, indicatorMargin, indicatorMargin);
    //添加指示器容器布局到SliderLayout
    addView(indicatorContainer, params);

    //初始化指示器,并添加到指示器容器布局
    for (int i = 0; i < itemCount; i++) {
        ImageView indicator = new ImageView(getContext());
        indicator.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        indicator.setPadding(indicatorSpace, indicatorSpace, indicatorSpace, indicatorSpace);
        indicator.setImageDrawable(unSelectedDrawable);
        indicatorContainer.addView(indicator);
    }
    LoopPagerAdapter pagerAdapter = new LoopPagerAdapter(views);
    pager.setAdapter(pagerAdapter);
    //设置当前item到Integer.MAX_VALUE中间的一个值,看起来像无论是往前滑还是往后滑都是ok的
    //如果不设置,用户往左边滑动的时候已经划不动了
    int targetItemPosition = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % itemCount;
    pager.setCurrentItem(targetItemPosition);
    switchIndicator(targetItemPosition % itemCount);//addOnPageChangeListener
    pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            switchIndicator(position % itemCount);
        }
    });
    startAutoPlay();

}

public void setSliderTransformDuration(int duration) {
    try {
        Field mScroller = ViewPager.class.getDeclaredField("mScroller");
        mScroller.setAccessible(true);
        FixedSpeedScroller scroller = new FixedSpeedScroller(pager.getContext(), null, duration);
        mScroller.set(pager, scroller);
    } catch (Exception e) {


    }
}

/**
 * 开始自动轮播
 */
public void startAutoPlay() {
    stopAutoPlay(); // 避免重复消息
    if (isAutoPlay) {
        handler.sendEmptyMessageDelayed(WHAT_AUTO_PLAY, autoPlayDuration);
    }
}

@Override
protected void onWindowVisibilityChanged(int visibility) {
    super.onWindowVisibilityChanged(visibility);
    if (visibility == VISIBLE) {
        startAutoPlay();
    } else {
        stopAutoPlay();
    }
}

/**
 * 停止自动轮播
 */
public void stopAutoPlay() {
    if (isAutoPlay) {
        handler.removeMessages(WHAT_AUTO_PLAY);
    }
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            stopAutoPlay();
            break;
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
            startAutoPlay();
            break;
    }
    return super.dispatchTouchEvent(ev);
}

/**
 * 切换指示器状态
 *
 * @param currentPosition 当前位置
 */
private void switchIndicator(int currentPosition) {
    for (int i = 0; i < indicatorContainer.getChildCount(); i++) {
        ((ImageView) indicatorContainer.getChildAt(i)).setImageDrawable(i == currentPosition ? selectedDrawable : unSelectedDrawable);
    }
}


public void setOnBannerItemClickListener(OnBannerItemClickListener onBannerItemClickListener) {
    this.onBannerItemClickListener = onBannerItemClickListener;
}

public interface OnBannerItemClickListener {
    void onItemClick(int position);
}

public class LoopPagerAdapter extends PagerAdapter {
    private List<View> views;

    public LoopPagerAdapter(List<View> views) {
        this.views = views;
    }

    @Override
    public int getCount() {
        //Integer.MAX_VALUE = 2147483647
        return Integer.MAX_VALUE;
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        if (views.size() > 0) {
            //position % view.size()是指虚拟的position会在[0,view.size())之间循环
            View view = views.get(position % views.size());
            if (container.equals(view.getParent())) {
                container.removeView(view);
            }
            container.addView(view);
            return view;
        }
        return null;
    }

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

public class FixedSpeedScroller extends Scroller {

    private int mDuration = 1000;

    public FixedSpeedScroller(Context context) {
        super(context);
    }

    public FixedSpeedScroller(Context context, Interpolator interpolator) {
        super(context, interpolator);
    }

    public FixedSpeedScroller(Context context, Interpolator interpolator, int duration) {
        this(context, interpolator);
        mDuration = duration;
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }
}

}
显示图片我用的是 脸书的加载方式 ,你可以自行更换。
2.下面这是自定义的样式文件:
这里写图片描述
3.布局XML代码 如下

这里写图片描述
记得xml布局文件上加上这句话
xmlns:app=”http://schemas.android.com/apk/res-auto”
标明支持自定义控件。
implements BannerLayout.OnBannerItemClickListener
给广告图添加监听事件 。

/* 图片地址*/
private List imgurls = new ArrayList();
添加图片
bannerLayout.setViewUrls(imgurls);

基本就这些 可以完美的实现 自动广告轮播。 麻蛋 我直接复制代码居然不显示 各位见谅, 有不明白的欢迎留言!

我们一起共同进步!表示谢谢!如果有技术问题欢迎

加入我的QQ群 285526158.

喜欢的可以关注微信公众号,哪里每天都会推荐一篇开源项目Git项目地址在里欢迎订阅

这里写图片描述

猜你喜欢

转载自blog.csdn.net/u012162503/article/details/51385141