Android自定义轮播广告
1、首先我们来看看项目的结构,主要的代码是自定义控件Banner和BannerViewPagerAdapter。自定义控件的属性放在attrs.xml中

2、项目的attrs.xml,各个属性的含义我在控件中有说明
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="BannerImageViewPager">
<attr name="dotsBgAlpha" format="float" />
<attr name="dotsBlurImage" format="reference" />
<attr name="dotsFocusImage" format="reference" />
<attr name="dotsSpacing" format="dimension" />
<attr name="dotsViewHeight" format="dimension" />
<attr name="dotsBackground" format="reference|color" />
<attr name="autoChange" format="boolean" />
<attr name="changeInterval" format="integer" />
<attr name="android:scaleType" />
<attr name="android:gravity" />
<attr name="android:adjustViewBounds" />
</declare-styleable>
</resources>

1、public class Banner extends LinearLayout implements Runnable {
private ViewPager viewPager;
private LinearLayout viewDots;
private List<View> views;
//存放所有的点
private ImageView[] dotsImageViews ;
//当前选中点的ImageView
private ImageView tempImageView;
//当前选中位置
private int index = 0;
//当前是否滚动
private boolean isContinue = true;
//Banner点击事件
private OnSingleTouchListener mListener;
/** 触摸时按下的点 **/
private PointF downP = new PointF();
/** 触摸时当前的点 **/
private PointF curP = new PointF();
/**属性*/
private float dotsViewHeight;// 引导View的高度
private float dotsSpacing;// 点与点之间的间隔
private boolean autoChange;// 是否自动切换Banner
private int changeInterval;// 切换Banner的时间
private Drawable dotsFocusImage;// 当前选中的Dots
private Drawable dotsBlurImage;// 未选中的Dots
private Drawable dotsBackground;// 引导View的背景
private ScaleType scaleType;//view如果的图片的话使用
private boolean adjustViewBounds;//view如果的图片的话使用
private int dotsGravity;//
public Banner(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.BannerImageViewPager, 0, 0);
try {
dotsViewHeight = a.getDimension(
R.styleable.BannerImageViewPager_dotsViewHeight,
dp2px(context, 45));
dotsSpacing = a.getDimension(
R.styleable.BannerImageViewPager_dotsSpacing,
dp2px(context, 10));
changeInterval = a.getInteger(
R.styleable.BannerImageViewPager_changeInterval, 3000);
autoChange = a.getBoolean(
R.styleable.BannerImageViewPager_autoChange, true);
dotsFocusImage = a
.getDrawable(R.styleable.BannerImageViewPager_dotsFocusImage);
dotsBlurImage = a
.getDrawable(R.styleable.BannerImageViewPager_dotsBlurImage);
dotsBackground = a
.getDrawable(R.styleable.BannerImageViewPager_dotsBackground);
ScaleType[] values = ScaleType.values();
int val = a.getInt(R.styleable.BannerImageViewPager_android_scaleType,0);
scaleType = values[val];
adjustViewBounds =
a.getBoolean(R.styleable.BannerImageViewPager_android_adjustViewBounds, false);
dotsGravity = a.getInt(R.styleable.BannerImageViewPager_android_gravity, Gravity.CENTER);
} finally {
// 回收TypedArray,以便后面重用
a.recycle();
}
InitBannerView();
}
private void InitBannerView() {
viewPager = new ViewPager(getContext());
viewDots = new LinearLayout(getContext());
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
addView(viewPager, lp);
if (dotsBackground != null) {
viewDots.setBackground(dotsBackground);
}
LayoutParams dotlp = new LayoutParams(LayoutParams.MATCH_PARENT,
(int)dotsViewHeight);
viewDots.setPadding((int) dotsSpacing, 0, 0, 0);
viewDots.setGravity(dotsGravity);
addView(viewDots, dotlp);
}
@SuppressWarnings("deprecation")
public void setViewPagerViews(List<View> views){
this.views = views;
dotsImageViews = new ImageView[views.size()];
addDots(views.size());
viewPager.setAdapter(new BannerViewPagerAdapter(views,scaleType,adjustViewBounds));
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
super.onPageSelected(position);
index = position;
switchToDot(index);
}
private void switchToDot(int index) {
if(tempImageView != null){
tempImageView.setImageDrawable(dotsBlurImage);
}
dotsImageViews[index].setImageDrawable(dotsFocusImage);
tempImageView = dotsImageViews[index];
}
});
viewPager.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//每次进行onTouch事件都记录当前的按下的坐标
curP.x = event.getX();
curP.y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//切记不可用 downP = curP ,这样在改变curP的时候,downP也会改变
downP.x = event.getX();
downP.y = event.getY();
case MotionEvent.ACTION_MOVE:
isContinue = false;
break;
case MotionEvent.ACTION_UP:
isContinue = true;
//在up时判断是否按下和松手的坐标为一个点
//如果是一个点,将执行点击事件,这是我自己写的点击事件,而不是onclick
if(downP.x==curP.x && downP.y==curP.y){
mListener.onSingleTouch(index);
return true;
}
break;
default:
isContinue = true;
break;
}
return false;
}
});
new Thread(this).start();
}
private void addDots(int size) {
for (int i = 0; i < size ; i++) {
ImageView imageView = new ImageView(getContext());
LayoutParams params = new LayoutParams(
LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
params.setMargins(0, 0, (int)dotsSpacing, 0);
imageView.setLayoutParams(params);
dotsImageViews[i] = imageView;
//默认选中的是第一张图片,此时第一个小圆点是选中状态,其他不是
if(i==0){
dotsImageViews[i].setImageDrawable(dotsFocusImage);
tempImageView = dotsImageViews[i];
}else{
dotsImageViews[i].setImageDrawable(dotsBlurImage);
}
viewDots.addView(dotsImageViews[i]);
}
}
@Override
public void run() {
while (autoChange) {
if (isContinue) {
pageHandler.sendEmptyMessage(index);
index = (index + 1) % views.size();
try {
Thread.sleep(changeInterval);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Handler pageHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
viewPager.setCurrentItem(msg.what);
super.handleMessage(msg);
}
};
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
View child = this.getChildAt(0);
child.layout(0, 0, getWidth(), getHeight());
if (changed) {
child = this.getChildAt(1);
child.measure(r - l, (int) dotsViewHeight);
child.layout(0, getHeight() - (int) dotsViewHeight, getWidth(),
getHeight());
}
}
public void setOnSingleTouchListener(OnSingleTouchListener mListener){
this.mListener = mListener;
}
public interface OnSingleTouchListener{
public void onSingleTouch(int position);
}
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dp2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
1、Xml中使用
<com.example.banner.Banner
android:id="@+id/my_view_pager"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="fitXY"
daemon:changeInterval="1000"
android:gravity="right|center_vertical"
daemon:dotsBackground="#99999999"
daemon:dotsBlurImage="@drawable/message_no_read"
daemon:dotsFocusImage="@drawable/message_read"
daemon:dotsSpacing="5dp"
daemon:dotsViewHeight="30dp" />

2、在代码中使用
views = new ArrayList<View>();
Banner pager = (Banner)findViewById(R.id.my_view_pager);
ImageView image = new ImageView(this);
image.setImageResource(R.drawable.image1);
views.add(image);
image = new ImageView(this);
image.setImageResource(R.drawable.image2);
views.add(image);
image = new ImageView(this);
image.setImageResource(R.drawable.image3);
views.add(image);
image = new ImageView(this);
image.setImageResource(R.drawable.image4);
views.add(image);
pager.setViewPagerViews(views);
pager.setOnSingleTouchListener(new OnSingleTouchListener() {
@Override
public void onSingleTouch(int position) {
Toast.makeText(MainActivity.this, "当前点击"+position, 0).show();
}
});

3、在使用中要注意属性不要出错,不然会崩溃!具体的实现我放在百度云盘上面,请下载查看。相信大家下载修改一下就可以使用了