ViewPager实现图片轮播,下方带小点显示当前位置
2016-06-07 11:52
721 查看
先来张效果图
还是从布局文件开始说,使用到的布局文件就一个content_main.xml,因为小点图片是覆盖在大图片的上面的,所以这里要用Framelayout,包含了两个linearLayout,一个放置大图片,一个放置小图片的,这里在代码中动态添加,具体代码如下:
源码下载
还是从布局文件开始说,使用到的布局文件就一个content_main.xml,因为小点图片是覆盖在大图片的上面的,所以这里要用Framelayout,包含了两个linearLayout,一个放置大图片,一个放置小图片的,这里在代码中动态添加,具体代码如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/activity_main" tools:context=".MainActivity"> <TextView android:id="@+id/test_hello" android:text="点击切换" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/newsHead_layout"/> <FrameLayout android:id="@+id/newsHead_layout" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:id="@+id/view_pager_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> </LinearLayout> <LinearLayout android:id="@+id/news_headView_dot" android:layout_width="wrap_content" android:layout_height="20dp" android:layout_gravity="bottom|right" android:layout_marginRight="10dp" android:gravity="center" android:orientation="horizontal"></LinearLayout> </FrameLayout> </RelativeLayout>对应的类为MainActivity,具体代码如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener, ListView.OnItemClickListener{ private ImageHandler handler = new ImageHandler(new WeakReference<MainActivity>(this)); private ViewPager vp; private List<View> ivs;//大图集合 private List<ImageView> dotIvs;//小点集合 private int currentPosition = 0;// 记录当前图片的位置 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.content_main); ivs = new ArrayList<View>(); dotIvs = new ArrayList<ImageView>(); 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<MainActivity> weakReference; private int currentItem = 0; protected ImageHandler(WeakReference<MainActivity> 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; } } } }代码中注释已经很详细了,这里就不在说明,大家有问题的可以给我留言
源码下载
相关文章推荐
- smarty 练习: 分页查询
- 2016年度最受欢迎的100个 Java 库
- 使用 终端 添加生成两份SSH Key
- 实例讲解Linux系统中硬链接与软链接的创建
- extjs6 基础组件扩展和自定义组件封装--01前言
- 界面延迟刷新
- 虚拟机对象是否还有引用
- JAVA POI 导出EXCEL: 代码中不需关心excel样式格式的实现思路 (反射)
- 内核新手区
- JS 百度地图导航
- android一键代理IP,安卓代理IP
- Android中的网络编程
- 将Library上传到Jcenter
- plupload
- Java 中 int与Integer的区别
- 多线程编程题
- MD5加盐算法(JAVA)
- Django1.96使用mysql数据库
- 机器学习是什么?
- Unity中网格合并示例研究。针对合并子网格列表后再合并网格