自定义ViewPager实现图片自动切换
2015-09-23 15:28
369 查看
最近项目刚上线测试版,现在闲下来两天,赶紧就捣鼓了些新功能。于是乎就写了个ViewPager的图片切换器。这个功能很实用,大多APP都有用到,所以花了点时间,给以后开发储备点 成熟的资源。
先给大家看看效果图:
是不是很顺溜,当然网上也有很多这样的控件、插件,但是自己实现起来也不太复杂。
当然写这个东西前,我先考虑的是 我怎么用这个空间才会比较方便,所以我直接先调用这个控件,新建一个类GalleryViewPager类,可以是空的,我们慢慢补充。然后在 Activity 里我想这样调用
参数待定,这样我们的结构雏形也就形成了。然后我们就可以去实现GalleryViewPager类的代码了。这个控件里有个ViewPager,然后需要个LineaLayout作为下边切换点的容器,容器背景半透明,点的个数与ViewPager的项一样。考虑这些,所以整个控件继承自FrameLayout,有两个子View——ViewPager和LineaLayout。又因为需要自动切换,所以实现了Runable借口。代码见下:
然后就是自定义适配器继承ViewAdapter,重写instantiateItem方法
到这里功能可以实现了,但是发现图片切换太快,不完美,viewPager.setCurrentItem(index) 而且android源码中把这个切换速度的代码写死了,并没有提供借口,所以采用Scroller类重新定义切换效果。
最后的调用方式
至此,所有工作都已完成。
转载请注明出处: /article/1822485.html
源码下载地址
GiHub托管源码
先给大家看看效果图:
是不是很顺溜,当然网上也有很多这样的控件、插件,但是自己实现起来也不太复杂。
当然写这个东西前,我先考虑的是 我怎么用这个空间才会比较方便,所以我直接先调用这个控件,新建一个类GalleryViewPager类,可以是空的,我们慢慢补充。然后在 Activity 里我想这样调用
GalleryViewPager.init(Object... params);
参数待定,这样我们的结构雏形也就形成了。然后我们就可以去实现GalleryViewPager类的代码了。这个控件里有个ViewPager,然后需要个LineaLayout作为下边切换点的容器,容器背景半透明,点的个数与ViewPager的项一样。考虑这些,所以整个控件继承自FrameLayout,有两个子View——ViewPager和LineaLayout。又因为需要自动切换,所以实现了Runable借口。代码见下:
package com.jerry.switcher.cutomview; import android.content.Context; import android.graphics.Color; import android.os.Handler; import android.os.Message; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import com.jerry.switcher.R; import com.jerry.switcher.cutomview.adapter.GalleryPageAdapter; import java.util.List; import java.util.Timer; import java.util.TimerTask; /** * Created by jerry on 2015/9/23. */ public class GalleryViewPager extends FrameLayout implements ViewPager.OnPageChangeListener, Runnable{ Context context; ViewPager viewPager; LinearLayout pointContainer; //导航点的容器 Handler handler; int index = 0; //当前活动页面索引 int millis; //每次滑动之间的时间间隔 int duration; //滑动动画速度 boolean isAutoSliding = true; public GalleryViewPager(Context context) { super(context); } public GalleryViewPager(Context context, AttributeSet attrs) { super(context, attrs); } /** * @param context context * @param container 导航点的容器 * @param viewList 填充 ViewPager 的View项 * @param isAutoSliding 是否自动滑动 * @param millis 每次滑动之间的间隔 * @param duration 滑动速度 */ public static void init( Context context, LinearLayout container, final List<Integer> viewList, boolean isAutoSliding, int millis, int duration){ final GalleryViewPager galleryViewPager= new GalleryViewPager(context); galleryViewPager.context = context; galleryViewPager.millis = millis; galleryViewPager.duration = duration; galleryViewPager.isAutoSliding = isAutoSliding; galleryViewPager.viewPager = new ViewPager(context); galleryViewPager.viewPager.setAdapter(new GalleryPageAdapter(context, viewList)); galleryViewPager.viewPager.addOnPageChangeListener(galleryViewPager); ViewPagerScroller scroller = new ViewPagerScroller(context); scroller.initViewPagerScroll(galleryViewPager.viewPager, duration); //自定义滑动时间 //修饰导航点的 容器样式 galleryViewPager.pointContainer = new LinearLayout(context); galleryViewPager.pointContainer.setBackgroundColor(Color.argb(60, 0, 0, 0)); galleryViewPager.pointContainer.setPadding(0, 20, 0, 20); galleryViewPager.pointContainer.setGravity(Gravity.CENTER); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT); params.gravity = Gravity.BOTTOM; galleryViewPager.pointContainer.setLayoutParams(params); //添加点到容器,数量与ViewPager项相等 for(int i = 0; i < viewList.size(); i++) { ImageView img = new ImageView(context); img.setImageResource(i == 0 ? R.drawable.radio_yes : R.drawable.radio_no); galleryViewPager.pointContainer.addView(img); } galleryViewPager.addView(galleryViewPager.viewPager); galleryViewPager.addView(galleryViewPager.pointContainer); container.addView(galleryViewPager); galleryViewPager.handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(galleryViewPager.index == viewList.size() - 1) { galleryViewPager.viewPager.setCurrentItem(0); }else{ galleryViewPager.viewPager.setCurrentItem(galleryViewPager.index + 1); } } }; new Thread(galleryViewPager).start(); } void changePointDirect(int position){ int count = pointContainer.getChildCount(); for(int i = 0; i < count; i++) { ((ImageView) pointContainer.getChildAt(i)).setImageResource(i == position ? R.drawable.radio_yes : R.drawable.radio_no); } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { index = position; changePointDirect(position); } @Override public void onPageScrollStateChanged(int state) { } @Override public void run() { try { while (isAutoSliding) { Thread.sleep(millis); handler.sendEmptyMessage(0); } }catch (InterruptedException e){ Log.e("GalleryViewPager error", "GalleryViewPager run error:" + e.getMessage()); } } }
然后就是自定义适配器继承ViewAdapter,重写instantiateItem方法
package com.jerry.switcher.cutomview.adapter; import android.content.Context; import android.support.v4.view.PagerAdapter; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import com.jerry.switcher.R; import java.util.List; /** * Created by jerry on 2015/9/23. */ public class GalleryPageAdapter extends PagerAdapter { Context context; List<Integer> resList; public GalleryPageAdapter(Context context, List<Integer> resList){ this.context = context; this.resList = resList; } @Override public int getCount() { return resList.size(); } @Override public boolean isViewFromObject(View view, Object o) { return view == o; } @Override public Object instantiateItem(ViewGroup container, int position) { ImageView img = new ImageView(context); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); img.setImageResource(resList.get(position)); img.setLayoutParams(params); img.setScaleType(ImageView.ScaleType.CENTER_CROP); container.addView(img); return img; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View)object); } }
到这里功能可以实现了,但是发现图片切换太快,不完美,viewPager.setCurrentItem(index) 而且android源码中把这个切换速度的代码写死了,并没有提供借口,所以采用Scroller类重新定义切换效果。
package com.jerry.switcher.cutomview; import android.content.Context; import android.support.v4.view.ViewPager; import android.view.animation.Interpolator; import android.widget.Scroller; import java.lang.reflect.Field; /** * Created by jerry on 2015/9/23. */ public class ViewPagerScroller extends Scroller { private int mScrollDuration = 2000; // 滑动速度,默认是2秒 public ViewPagerScroller(Context context) { super(context); } public ViewPagerScroller(Context context, Interpolator interpolator) { super(context, interpolator); } @Override public void startScroll(int startX, int startY, int dx, int dy, int duration) { super.startScroll(startX, startY, dx, dy, mScrollDuration); } @Override public void startScroll(int startX, int startY, int dx, int dy) { super.startScroll(startX, startY, dx, dy, mScrollDuration); } public void initViewPagerScroll(ViewPager viewPager, int duration) { this.mScrollDuration = duration; try { Field mScroller = ViewPager.class.getDeclaredField("mScroller"); mScroller.setAccessible(true); mScroller.set(viewPager, this); } catch(Exception e) { Log.e("ViewPagerScroller error", "ViewPagerScroller initViewPagerScroll error" + e.getMessage()); } } }
最后的调用方式
LinearLayout pagerContainer = (LinearLayout) findViewById(R.id.image_pager_container); List<Integer> resList = new ArrayList<>(); resList.add(R.drawable.one); resList.add(R.drawable.two); resList.add(R.drawable.three); resList.add(R.drawable.four); resList.add(R.drawable.five); resList.add(R.drawable.six); GalleryViewPager.init(this, pagerContainer, resList, true, 2000, 1000);
至此,所有工作都已完成。
转载请注明出处: /article/1822485.html
源码下载地址
GiHub托管源码
相关文章推荐
- 第三次作业
- ButterKnife--View注入框架
- 响应式导航页面
- 如何重置硬盘遭到“损坏”的Linux系统root用户密码
- C#及WPF获取本机所有字体和颜色的方法
- Unsafe初涉
- 字符串笔试题
- cocosstudio 出现项目由更新版本编辑器产生 无法打开的解决方法
- 查看/修改Linux时区和时间
- SQLSERVER 备份还原1
- 第十四章 Vim之替换
- DNS服务
- 通用js函数集锦<来源于网络/自己> 【一】
- 三维数组—— 与宝玉QQ群交流 之三
- SQL语句创建数据库及表
- ebtables
- 关于IOS判断字符串长度的方法
- C++ 数据抽象、数据封装与接口(抽象类)
- spring mvc freemaker form表单提交
- 第十三章 查找