我们在做一些App开发的时候经常会遇到有广告轮播的地方,今天我写了一种方式来供大家参考
1、效果图如下
2、页面布局源码
<LinearLayout 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"
android:orientation="vertical"
tools:context=".MainActivity" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="180dp" >
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="180dp" />
<LinearLayout
android:id="@+id/dotLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="right|bottom"
android:orientation="horizontal"
android:background="#a0000000"
android:padding="8dp" >
<View
android:id="@+id/v_dot1"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@mipmap/af_01_icon_graycircle720" />
<View
android:id="@+id/v_dot2"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginLeft="5dp"
android:background="@mipmap/af_01_icon_greencircle720" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
3、class类的源码
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.ImageView;
import android.widget.LinearLayout;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
/**
* 实现广告无限循环滑动
*/
public class MainActivity extends Activity implements View.OnTouchListener {
private ImageHandler mHandler = new ImageHandler(new WeakReference<MainActivity>(this));
private ViewPager mViewPager;
// 自定义轮播图的资源
private int[] mImageResIds = {R.mipmap.lp_1, R.mipmap.lp_2, R.mipmap.lp_3, R.mipmap.lp_4, R.mipmap.lp_5};
// 放轮播图片的ImageView 的list
private List<ImageView> mImageList = new ArrayList<ImageView>();
// 放圆点的View的list
private List<View> mDotList = new ArrayList<View>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
// 初始化iewPager的内容
mViewPager = (ViewPager) findViewById(R.id.view_pager);
LinearLayout dotLayout = (LinearLayout) findViewById(R.id.dotLayout);
dotLayout.removeAllViews();
for (int i = 0; i < mImageResIds.length; i++) {
ImageView imageView = new ImageView(MainActivity.this);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
// view.setTag(mImageResId[i]);
imageView.setImageResource(mImageResIds[i]);
mImageList.add(imageView);
View dotView = new View(MainActivity.this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(getResources().getDimensionPixelSize(R.dimen.dot_width),
getResources().getDimensionPixelSize(R.dimen.dot_width));
params.setMargins(4, 0, 4, 0);
dotView.setLayoutParams(params);
// if (i == 0) {
// dotView.setBackgroundResource(R.mipmap.af_01_icon_greencircle720);
// } else {
// dotView.setBackgroundResource(R.mipmap.af_01_icon_graycircle720);
// }
dotLayout.addView(dotView);
mDotList.add(dotView);
}
mViewPager.setAdapter(new ImageAdapter(mImageList));
mViewPager.setOnPageChangeListener(new PageChangeListener());
mViewPager.setFocusable(true);
mViewPager.setCurrentItem(Integer.MAX_VALUE / 2);// 默认在中间,使用户看不到边界
mViewPager.setOnTouchListener(this);
// 开始轮播效果
mHandler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mHandler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mHandler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
break;
}
return false;
}
private class PageChangeListener implements ViewPager.OnPageChangeListener {
// 配合Adapter的currentItem字段进行设置。
@Override
public void onPageSelected(int position) {
mHandler.sendMessage(Message.obtain(mHandler, ImageHandler.MSG_PAGE_CHANGED, position, 0));
}
@Override
public void onPageScrolled(int position, float arg1, int arg2) {
}
// 覆写该方法实现轮播效果的暂停和恢复
@Override
public void onPageScrollStateChanged(int state) {
switch (state) {
case ViewPager.SCROLL_STATE_DRAGGING:
mHandler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);
break;
case ViewPager.SCROLL_STATE_IDLE:
mHandler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
break;
default:
break;
}
}
}
private class ImageAdapter extends PagerAdapter {
private List<ImageView> viewlist;
public ImageAdapter(List<ImageView> viewlist) {
this.viewlist = viewlist;
}
@Override
public int getCount() {
// 设置成最大,使用户看不到边界
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// Warning:不要在这里调用removeView
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// 对ViewPager页号求模取出View列表中要显示的项
position %= viewlist.size();
if (position < 0) {
position = viewlist.size() + position;
}
ImageView view = viewlist.get(position);
// 如果View已经在之前添加到了一个父组件,则必须先remove,否则会抛出IllegalStateException。
ViewParent vp = view.getParent();
if (vp != null) {
ViewGroup parent = (ViewGroup) vp;
parent.removeView(view);
}
container.addView(view);
// 此处可添加监听事件
return view;
}
}
private static class ImageHandler extends Handler {
/**
* 请求更新显示的View。
*/
protected static final int MSG_UPDATE_IMAGE = 1;
/**
* 请求暂停轮播。
*/
protected static final int MSG_KEEP_SILENT = 2;
/**
* 请求恢复轮播。
*/
protected static final int MSG_BREAK_SILENT = 3;
/**
* 记录最新的页号,当用户手动滑动时需要记录新页号,否则会使轮播的页面出错。
* 例如当前如果在第一页,本来准备播放的是第二页,而这时候用户滑动到了末页,
* 则应该播放的是第一页,如果继续按照原来的第二页播放,则逻辑上有问题。
*/
protected static final int MSG_PAGE_CHANGED = 4;
// 轮播间隔时间
protected static final long MSG_DELAY = 3000;
// 使用弱引用避免Handler泄露.这里的泛型参数可以不是Activity,也可以是Fragment等
private WeakReference<MainActivity> weakReference;
private int currentItem = 0;
// private boolean isOnce = true;
protected ImageHandler(WeakReference<MainActivity> wk) {
weakReference = wk;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
final MainActivity mainActivity = weakReference.get();
if (mainActivity == null) {
// Activity已经回收,无需再处理UI了
return;
}
// 第一次不删重复的消息
if (currentItem != 0) {
// 检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。
if (mainActivity.mHandler.hasMessages(MSG_UPDATE_IMAGE)) {
mainActivity.mHandler.removeMessages(MSG_UPDATE_IMAGE);
}
}
switch (msg.what) {
case MSG_UPDATE_IMAGE:
currentItem++;
mainActivity.mViewPager.setCurrentItem(currentItem);
// 准备下次播放
mainActivity.mHandler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
break;
case MSG_KEEP_SILENT:
// 只要不发送消息就暂停了
break;
case MSG_BREAK_SILENT:
mainActivity.mHandler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
break;
case MSG_PAGE_CHANGED:
// 记录当前的页号,避免播放的时候页面显示不正确。
int position = msg.arg1;
int lastIndex = 0;
int index = position % mainActivity.mImageList.size();
for (int i = 0; i < mainActivity.mDotList.size(); i++) {
mainActivity.mDotList.get(i).setBackgroundResource(R.mipmap.af_01_icon_graycircle720);
}
if (mainActivity.mDotList.get(index) != null) {
mainActivity.mDotList.get(index).setBackgroundResource(R.mipmap.af_01_icon_greencircle720);
}
lastIndex = index;
currentItem = position;
break;
default:
break;
}
}
}
}
希望对大家有所帮助,不足的地方还请多多指教
源码下载地址: