还是从布局文件开始说,使用到的布局文件就一个content_main.xml,因为小点图片是覆盖在大图片的上面的,所以这里要用Framelayout,包含了两个linearLayout,一个放置大图片,一个放置小图片的,这里在代码中动态添加,具体代码如下:
对应的类为MainActivity,具体代码如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener,
ListView.OnItemClickListener{
private ImageHandler handler = new ImageHandler(new WeakReference(this));
private ViewPager vp;
private List ivs;//大图集合
private List dotIvs;//小点集合
private int currentPosition = 0;// 记录当前图片的位置
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
ivs = new ArrayList();
dotIvs = new ArrayList();
initHeadView();
TextView tvHello = (TextView)findViewById(R.id.test_hello);
tvHello.setOnClickListener(this);
}
private void initHeadView() {
LinearLayout pagerLayout = (LinearLayout) findViewById(R.id.view_pager_content);
vp = new ViewPager(this);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
//设置viewpager的宽高,高是宽度的特定比例,我的手机宽是720的,做了下适配
vp.setLayoutParams(new LinearLayout.LayoutParams(dm.widthPixels, dm.widthPixels * 462 / 720));
pagerLayout.addView(vp);
ivs.clear();
dotIvs.clear();
//这里有三张图片,所以i<3
for (int i = 0; i < 3; i++) {
ImageView iv = new ImageView(this);
iv.setId(i);// 处理其点击事件
iv.setOnClickListener(this);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
// manager.bindBitmap(iv, mainNews.get(i).getPicUrl());
// iv.setBackgroundResource(R.id.main_logo);
if (i == 0) {
iv.setImageResource(R.drawable.rolling1);
} else if (i == 1) {
iv.setImageResource(R.drawable.rolling2);
} else if (i == 2) {
iv.setImageResource(R.drawable.rolling3);
}
ivs.add(iv);// 加入大图集合
ImageView dotIv = new ImageView(this);
dotIv.setImageResource(R.drawable.s_banner_unselect);
dotIv.setPadding(5, 0, 5, 0);//设置小点的间距left top right bottom
dotIvs.add(dotIv);// 加入小点集合
}
//小点所在的linearlayout
LinearLayout dotsLl = (LinearLayout) findViewById(R.id.news_headView_dot);
dotsLl.removeAllViews();
for (int i = 0; i < dotIvs.size(); i++) {
dotsLl.addView(dotIvs.get(i));
}
// TODO Auto-generated method stub
if (ivs.size() == 0) {
return;
}
vp.setAdapter(new FVpAdapter());
// vp.setCurrentItem(Integer.MAX_VALUE/2);//默认在中间,使用户看不到边界
//开始轮播效果
handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
vp.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
// Toast.makeText(MainSlidingMenuActivity.this, "这是第" + arg0 % dotIvs.size() + "张图片", Toast.LENGTH_SHORT).show();
currentPosition = arg0;
handler.sendMessage(Message.obtain(handler, ImageHandler.MSG_PAGE_CHANGED, arg0, 0));
//
selector(currentPosition);
}
//覆写该方法实现轮播效果的暂停和恢复
@Override
public void onPageScrollStateChanged(int arg0) {
switch (arg0) {
case ViewPager.SCROLL_STATE_DRAGGING:
handler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);
break;
case ViewPager.SCROLL_STATE_IDLE:
handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
break;
default:
break;
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
});
// 更改viewPager的属性
try {
Field mScroller;
mScroller = ViewPager.class.getDeclaredField("mScroller");
mScroller.setAccessible(true);
FixedSpeedScroller scroller = new FixedSpeedScroller(
vp.getContext());// 调用这个构造方法即可
// scroller.setFixedDuration(5000);
mScroller.set(vp, scroller);
} catch (NoSuchFieldException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}
vp.setCurrentItem(currentPosition);// 从这个位置开始前后都可以无限滑动
vp.getNextFocusUpId();
selector(currentPosition);
}
//选择小点的方法
private void selector(int index) {
if (dotIvs.size() == 0) {
return;
}
index = index % dotIvs.size();
int len = dotIvs.size();
for (int i = 0; i < len; i++) {
if (index == i) {
dotIvs.get(i).setImageResource(R.drawable.s_banner_select);
} else {
dotIvs.get(i).setImageResource(R.drawable.s_banner_unselect);
}
}
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.test_hello:
Toast.makeText(MainActivity.this, "hello", Toast.LENGTH_SHORT).show();
int count = ivs.size();
//设置点击切换,如果到头则重新开始
int item = currentPosition+1 == count? 0 : currentPosition+1;
vp.setCurrentItem(item,true);
break;
}
}
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
}
class FVpAdapter extends PagerAdapter {
@Override
public int getCount() {
// TODO Auto-generated method stub
// return ivs.size();
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0 == arg1;
}
@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
// TODO Auto-generated method stub
//不把划过去的View清空,否则再往回滑的话会变空白的View
//((ViewPager) arg0).removeView(ivs.get(arg1 % ivs.size()));
}
@Override
public Object instantiateItem(View arg0, int arg1) {
// TODO Auto-generated method stub
try {
// ((ViewPager) arg0).addView(list.get(arg1),0);
// ((ViewPager) arg0).removeView(ivs.get(arg1 % ivs.size()));
((ViewPager) arg0)
.addView(ivs.get(arg1 % ivs.size()));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return ivs.get(arg1 % ivs.size());
}
}
// 自定义scroller更改viewPager默认的切换时间
class FixedSpeedScroller extends Scroller {
//切换一秒钟
private int mDuration = 1000;
public FixedSpeedScroller(Context context) {
super(context);
}
public FixedSpeedScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
@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);
}
}
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 weakReference;
private int currentItem = 0;
protected ImageHandler(WeakReference wk){
weakReference = wk;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
MainActivity activity = weakReference.get();
if (activity==null){
//Activity已经回收,无需再处理UI了
return ;
}
//检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。
if (activity.handler.hasMessages(MSG_UPDATE_IMAGE)){
//次句不加,更换变得很不稳定
activity.handler.removeMessages(MSG_UPDATE_IMAGE);
}
switch (msg.what) {
case MSG_UPDATE_IMAGE:
currentItem++;
activity.vp.setCurrentItem(currentItem);
//准备下次播放
activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
break;
case MSG_KEEP_SILENT:
//只要不发送消息就暂停了
break;
case MSG_BREAK_SILENT:
activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
break;
case MSG_PAGE_CHANGED:
//记录当前的页号,避免播放的时候页面显示不正确。
currentItem = msg.arg1;
break;
default:
break;
}
}
}
}
代码中注释已经很详细了,这里就不在说明,大家有问题的可以给我留言