自定义viewpager 三张图片在同一屏幕轮播的效果
来源:互联网 发布:淘宝客服是什么工作 编辑:程序博客网 时间:2024/05/01 12:21
ps:刚开始写文章,有点乱,慢慢改进。
最下方项目源码下载
github:https://github.com/nickeyCode/RoundImageViewPager
说实话不知道怎么描述这个效果,在网页上见得跟多,公司要求做这个效果得时候不知道怎么用文字描述找不到对应的dome只好自己写。
先上图
大概效果就是这个。主要用的的知识点就是viewpager的自定义动画。
项目目录:
roundimg是圆形图片,继承ImageView的,上网好多可以搜索得到
viewpager主要分成三部分
一是viewpager本身,设置adapter,绑定监听器等。
二是adapter,继承PagerAdapter,用法跟listview的差不多。
三是动画类,继承PageTransformer。
首先看看最核心的动画类(能做到这个效果就是根据对应的动画变动)
HeadViewPagerTransformer.java
public class HeadViewPagerTransformer implements PageTransformer{private static final float MIN_SCALE = 0.75f; //主要是设置在不同位置上的VIEW的活动动画@Overridepublic void transformPage(View view, float position) {// TODO Auto-generated method stub int pageWidth = view.getWidth(); if (position < -1) { // [-Infinity,-1) view.setAlpha(0); } else if (position <= 0) { // [-1,0] view.setAlpha(1); view.setTranslationX(0); float x = -1.0f * (2f / 3f) * pageWidth * position; view.setTranslationX(x); float scaleFactor = MIN_SCALE + (2 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } else if (position <= 1) { // (0,1] view.setAlpha(1); float x = -1.0f * (2f / 3f) * pageWidth * position; view.setTranslationX(x); float scaleFactor = MIN_SCALE + (2 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); }}}
因为在这个类中,viewpager中view都有对应的位置编号,在正中间显示的view位置是0
在左边的view位置是-1,在右边的view位置是1.(相当于一个坐标轴)
只要viewpager发生滑动,就会调用tansFromPager();position之说以是float类型,是因为如果发生滑动,位置就会有对应的变化,而变化精确到0.0001.
在函数中使用if-else来设定在不同位置区间中的view的动画变化;
if (position < -1) { // [-Infinity,-1) view.setAlpha(0); }这是负无穷到-1的区间,当然,如果你的viewpager缓存的view只有三个的话,这个就没有作用了,因为最多只有三个view,多出来就销毁了。
else if (position <= 0) { // [-1,0] view.setAlpha(1); view.setTranslationX(0); float x = -1.0f * (2f / 3f) * pageWidth * position; view.setTranslationX(x); float scaleFactor = MIN_SCALE + (2 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); }这是-1到0的区间,就是左边的view到中间或中间的view到左边的动画效果,这里主要是做了两个动画变化,一是大小,二是位置。
这两个变化公式是根据位置的变化与动画数值的关系,解二元一次方程求出来的(初中数学知识。。。。)
具体方式就是balbalblabalbalb。。。。。(不多说)
同理
else if (position <= 1) { // (0,1] view.setAlpha(1); float x = -1.0f * (2f / 3f) * pageWidth * position; view.setTranslationX(x); float scaleFactor = MIN_SCALE + (2 - MIN_SCALE) * (1 - Math.abs(position)); }0到1的区间一样。在实际动画设计的过程中,公式是需要变动的。
剩下的都是普通的viewpager使用,设置adapter (HeadViewPagerAdapter.java)
public class HeadViewPagerAdapter extends PagerAdapter {private Context mContext;private List<MyImageView> mList;public HeadViewPagerAdapter(Context context,List<MyImageView> list){this.mContext = context;this.mList = list;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn mList.size();}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {// TODO Auto-generated method stubreturn arg0 == arg1;}//当缓存view的数量超过上限时,会销毁最先的一个@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {// TODO Auto-generated method stub//Log.d("remove", mImageViews[position].hashCode() + "");container.removeView(mList.get(position));}//添加View@Overridepublic Object instantiateItem(ViewGroup container, int position) {// TODO Auto-generated method stubcontainer.addView(mList.get(position),0);return mList.get(position);}}
还有就是对应的绑定:HeadViewPager.java
public class HeadViewPager extends FrameLayout {private Context mContext;private ViewPager mViewPager;private List<Integer> mImageIds;private List<MyImageView> mImageViews;private ViewGroup mViewGroup;private List<ImageView> tips;private int tipsChoseImgId;private int tipsUnchoseImgId;public HeadViewPager(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stubcreatView(context);}public HeadViewPager(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stubcreatView(context);}public HeadViewPager(Context context) {super(context);// TODO Auto-generated constructor stubcreatView(context);}public HeadViewPager(Context context,List<MyImageView> imgageList) {super(context);// TODO Auto-generated constructor stubcreatView(context,imgageList);}public void creatView(Context context){this.mContext = context;LayoutInflater.from(context).inflate(R.layout.head_view_pager, this);mViewPager = (ViewPager)findViewById(R.id.viewpager);mViewGroup = (ViewGroup)findViewById(R.id.viewgroup);mImageViews = new ArrayList<MyImageView>();mImageIds = new ArrayList<Integer>();tips = new ArrayList<ImageView>();tipsChoseImgId = R.drawable.img_bg_chose;tipsUnchoseImgId = R.drawable.img_bg_unchose;build();}public void creatView(Context context,List<MyImageView> imgageList){this.mContext = context;LayoutInflater.from(context).inflate(R.layout.head_view_pager, this);mViewPager = (ViewPager)findViewById(R.id.viewpager);mViewGroup = (ViewGroup)findViewById(R.id.viewgroup);mImageViews = imgageList;mImageIds = new ArrayList<Integer>();tips = new ArrayList<ImageView>();tipsChoseImgId = R.drawable.img_bg_chose;tipsUnchoseImgId = R.drawable.img_bg_unchose;build();}public void build(){buildTips();mViewPager.setAdapter(new HeadViewPagerAdapter(mContext,mImageViews));//设置默认显示页面为第0页mViewPager.setCurrentItem(0);//设置选择页面时的动画mViewPager.setPageTransformer(true, new HeadViewPagerTransformer());//设置缓存View的个数,默认是3个,这表示缓存了5个mViewPager.setOffscreenPageLimit(4);//页面发生改变的监听器mViewPager.setOnPageChangeListener(new OnPageChangeListener() {//选择发生改变@Overridepublic void onPageSelected(int arg0) {// TODO Auto-generated method stubchangeTips(arg0);}//有滑动操作@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {// TODO Auto-generated method stub}//滑动操作或选择改变@Overridepublic void onPageScrollStateChanged(int arg0) {// TODO Auto-generated method stub}});}//初始化底部导航圆点条public void buildTips(){for (int i = 0 ; i < mImageViews.size() ; i ++){ ImageView imageView = new ImageView(mContext); imageView.setLayoutParams(new LayoutParams(10,10)); if(i == 0){ imageView.setBackgroundResource(tipsChoseImgId); }else{ imageView.setBackgroundResource(tipsUnchoseImgId); } LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(new ViewGroup.LayoutParams(12,12)); layoutParams.leftMargin = 5; layoutParams.rightMargin = 5; tips.add(imageView); mViewGroup.addView(imageView, layoutParams); }}//当选定的页面发生改变时,导航条也对应改变public void changeTips(int index){for (int i = 0 ; i < tips.size() ; i ++){ if(i == index){ tips.get(i).setBackgroundResource(tipsChoseImgId); }else{ tips.get(i).setBackgroundResource(tipsUnchoseImgId); } }}public Context getmContext() {return mContext;}public void setmContext(Context mContext) {this.mContext = mContext;}public ViewPager getmViewPager() {return mViewPager;}public void setmViewPager(ViewPager mViewPager) {this.mViewPager = mViewPager;}public List<MyImageView> getmImageViews() {return mImageViews;}//改变图片队列时,要更新整个viewPagerpublic void setmImageViews(List<MyImageView> mImageViews) {this.mImageViews = mImageViews;this.mViewPager.notify();this.mViewPager.setCurrentItem(0);}public ViewGroup getmViewGroup() {return mViewGroup;}public void setmViewGroup(ViewGroup mViewGroup) {this.mViewGroup = mViewGroup;}public int getTipsChoseImgId() {return tipsChoseImgId;}public void setTipsChoseImgId(int tipsChoseImgId) {this.tipsChoseImgId = tipsChoseImgId;}public int getTipsUnchoseImgId() {return tipsUnchoseImgId;}public void setTipsUnchoseImgId(int tipsUnchoseImgId) {this.tipsUnchoseImgId = tipsUnchoseImgId;}}
样例项目资源:
http://download.csdn.net/detail/nickey_1314/8932807
点击打开链接
- 自定义viewpager 三张图片在同一屏幕轮播的效果
- ViewPager详解(三)——自动轮播图片小于三张的问题解决
- Android之利用Viewpager实现图片的轮播效果
- 自定义ViewPager实现轮播效果
- android图片轮播效果viewPager
- ViewPager的图片轮播
- ViewPager轮播效果
- 在Android studio中使用viewpager创建出图片轮播效果
- viewpager实现简单的轮播效果
- CarouselViewPager实现ViewPager的轮播效果
- android-ViewPager的轮播效果
- ViewPager图片轮播
- 图片轮播ViewPager
- ViewPager+Handler实现图片自动轮播的效果
- ionic+三张图片进行轮播+按钮
- Android Viewpager实现图片轮播(仿优酷效果)
- Android Viewpager实现图片轮播(仿优酷效果)
- 使用ViewPager实现图片轮播效果(绝对好使)
- struts2之如何向服务器上传文件
- Spring AOP 实现原理
- 插入排序
- Python 获得命令行参数的方法
- linux 安装redis need tcl 8.5 or newer
- 自定义viewpager 三张图片在同一屏幕轮播的效果
- WEB标准
- 04 JAVA 常用类
- Java学习笔记-------执行语句为什么必须要放在方法里面???
- Raft一致性算法
- 《ASP.NET》数据绑定—DataList
- linux reshat redis 安装
- JS函数声明和函数表达式的区别
- openCV—Python(5)——图像几何变换