• Android 自定义viewpager 三张图片在同一屏幕轮播的效果


    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的活动动画
        @Override
        public 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;
        }
        
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return mList.size();
        }
    
        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            // TODO Auto-generated method stub
            return arg0 == arg1;
        }
        //当缓存view的数量超过上限时,会销毁最先的一个
        @Override
        public 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
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // TODO Auto-generated method stub
            container.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 stub
            creatView(context);
        }
    
        public HeadViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
            // TODO Auto-generated constructor stub
            creatView(context);
        }
    
        public HeadViewPager(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
            creatView(context);
        }
        
        public HeadViewPager(Context context,List<MyImageView> imgageList) {
            super(context);
            // TODO Auto-generated constructor stub
            creatView(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() {
                //选择发生改变
                @Override
                public void onPageSelected(int arg0) {
                    // TODO Auto-generated method stub
                    changeTips(arg0);
                }
                //有滑动操作
                @Override
                public void onPageScrolled(int arg0, float arg1, int arg2) {
                    // TODO Auto-generated method stub
                    
                }
                //滑动操作或选择改变
                @Override
                public 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;
        }
        //改变图片队列时,要更新整个viewPager
        public 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

    点击打开链接

  • 相关阅读:
    【代码审计】XDCMS 报错注入
    【渗透测试】MS17-010 "永恒之蓝" 修复方案
    【代码审计】MenInfo文件包含漏洞
    【代码总结】数据库抽象层PDO
    【代码总结】PHP面向对象之接口与多态性应用
    【代码总结】PHP面向对象之抽象类
    东哥手把手带你刷二叉树(第一期)
    二叉树的序列化,就那几个框架,枯燥至极
    二叉堆详解实现优先级队列
    递归反转链表的一部分
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/7366107.html
Copyright © 2020-2023  润新知