• Android实现图片轮显效果——自定义ViewPager控件


    一、问题概述

      使用ViewPager控件实现可横向翻页、水平切换图片等效果,但ViewPager需要手动滑动才能切换页面,图片轮显效果的效果本质上就是在ViewPager控件的基础上让它能自动的进行切换,所以实现图片轮显步骤如下:

    1、  扩展ViewPager自定义一个MyScrollImageView类

    2、  为MyScrollImageView定义适配器,装载图片信息

    3、  定义图片滑动动画时间控制类

      接下来我们就一步步实现下图案例:

    二、实现套路

    1、为自定义ViewPager控件编写适配器

      我们先为我们的自定义ViewPager控件编写一个适配器,用于加载要轮显的图片,这个和使用ViewPager控件一样都要为适配器控件定义适配器

        // 适配器
        public  class  MyPagerAdapter  extends PagerAdapter {
            private Activity mActivity; // 上下文
            private List<View> mListViews; // 图片组
            public MyPagerAdapter(){
            }
            public MyPagerAdapter(Activity mActivity,List<View> mListViews){
                this.mActivity=mActivity;
                this.mListViews=mListViews;
            }
            public int getCount() {
                if (mListViews.size() == 1) {// 一张图片时不用流动
                    return mListViews.size();
                }
                return Integer.MAX_VALUE;
            }
            /**
                返回List中的图片元素装载到控件中
    */
            public Object instantiateItem(View v, int i) {
                if (((ViewPager) v).getChildCount() == mListViews.size()) {
                    ((ViewPager) v)
                            .removeView(mListViews.get(i % mListViews.size()));
                }
                ((ViewPager) v).addView(mListViews.get(i % mListViews.size()), 0);
                return mListViews.get(i % mListViews.size());
            }
    
            public boolean isViewFromObject(View arg0, Object arg1) {
                return arg0 == (arg1);
            }
    
            public void destroyItem(ViewGroup view, int i, Object object) {
                view.removeView(mListViews.get(i%mListViews.size()));
            }
            
        }

    2、自定义一个MyScrollImageView类

      自定义一个MyScrollImageView类,主要扩展一个start(…)方法,该方法实现按时间间隔不断切换图片

    public class MyImgScroll extends ViewPager {
        Activity mActivity; // 上下文
        List<View> mListViews; // 图片组
        int mScrollTime = 0;
        Timer timer;
        int oldIndex = 0;
        int curIndex = 0;
    
        public MyImgScroll(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        /**
         * 开始广告滚动
         * 
         * @param mainActivity
         *            显示广告的主界面
         * @param imgList
         *            图片列表, 不能为null ,最少一张
         * @param scrollTime
         *            滚动间隔 ,0为不滚动
         * @param ovalLayout
         *            圆点容器,可为空,LinearLayout类型
         * @param ovalLayoutId
         *            ovalLayout为空时 写0, 圆点layout XMl
         * @param ovalLayoutItemId
         *            ovalLayout为空时 写0,圆点layout XMl 圆点XMl下View ID
         * @param focusedId
         *            ovalLayout为空时 写0, 圆点layout XMl 选中时的动画
         * @param normalId
         *            ovalLayout为空时 写0, 圆点layout XMl 正常时背景
         */
        public void start(Activity mainActivity, List<View> imgList,
                int scrollTime, LinearLayout ovalLayout, int ovalLayoutId,
                int ovalLayoutItemId, int focusedId, int normalId) {
            mActivity = mainActivity;
            mListViews = imgList;
            mScrollTime = scrollTime;
            // 设置圆点
            setOvalLayout(ovalLayout, ovalLayoutId, ovalLayoutItemId, focusedId,
                    normalId);
            this.setAdapter(new MyPagerAdapter(mActivity,mListViews));// 设置适配器
            if (scrollTime != 0 && imgList.size() > 1) {
                // 设置滑动动画时间  ,如果用默认动画时间可不用 ,反射技术实现
                 new FixedSpeedScroller(mActivity).setDuration(this, 700);
                startTimer();
                // 触摸时停止滚动
                this.setOnTouchListener(new OnTouchListener() {
                    public boolean onTouch(View v, MotionEvent event) {
                        if (event.getAction() == MotionEvent.ACTION_UP) {
                            startTimer();
                        } else {
                            stopTimer();
                        }
                        return false;
                    }
                });
            } 
            if (mListViews.size() > 1) {
                this.setCurrentItem((Integer.MAX_VALUE / 2)
                        - (Integer.MAX_VALUE / 2) % mListViews.size());// 设置选中为中间/图片为和第0张一样
            }
        }
    
        // 设置圆点
        private void setOvalLayout(final LinearLayout ovalLayout, int ovalLayoutId,
                final int ovalLayoutItemId, final int focusedId, final int normalId) {
            if (ovalLayout != null) {
                LayoutInflater inflater=LayoutInflater.from(mActivity);
                for (int i = 0; i < mListViews.size(); i++) {
                    ovalLayout.addView(inflater.inflate(ovalLayoutId, null));
                    
                }
                //选中第一个
                ovalLayout.getChildAt(0).findViewById(ovalLayoutItemId)
                .setBackgroundResource(focusedId);
                this.setOnPageChangeListener(new OnPageChangeListener() {
                    public void onPageSelected(int i) {
                        curIndex = i % mListViews.size();
                        //取消圆点选中
                        ovalLayout.getChildAt(oldIndex).findViewById(ovalLayoutItemId)
                                .setBackgroundResource(normalId);
                         //圆点选中
                        ovalLayout.getChildAt(curIndex).findViewById(ovalLayoutItemId)
                        .setBackgroundResource(focusedId);
                        oldIndex = curIndex;
                    }
    
                    public void onPageScrolled(int arg0, float arg1, int arg2) {
                    }
    
                    public void onPageScrollStateChanged(int arg0) {
                    }
                });
            }
        }
        /**
         * 取得当明选中下标
         * @return
         */
        public int getCurIndex() {
            return curIndex;
        }
        /**
         * 停止滚动
         */
        public void stopTimer() {
            if (timer != null) {
                timer.cancel();
                timer = null;
            }
        }
    
        /**
         * 开始滚动
         */
        public void startTimer() {
            timer = new Timer();
            timer.schedule(new TimerTask() {
                public void run() {
                    mActivity.runOnUiThread(new Runnable() {
                        public void run() {
                            MyImgScroll.this.setCurrentItem(MyImgScroll.this
                                    .getCurrentItem() + 1);//设置控件当前项(改变图片)
                        }
                    });
                }
            }, mScrollTime, mScrollTime);
        }
    
    }

    3、定义图片滑动动画时间控制类

    package com.tianshicoffeeom.app.imgscroll;
    import java.lang.reflect.Field;
    import android.content.Context;
    import android.support.v4.view.ViewPager;
    import android.view.animation.Interpolator;
    import android.widget.Scroller;
     /**
      * 图片滑动动画时间控制类  , 如果采用默认时间可不用这个类 ,通过反射技术改变ViewPager的滑动时间
      *
      */
    public class FixedSpeedScroller extends Scroller {  
        private Context context;
        private int mDuration = 500;  
        public FixedSpeedScroller(Context context) {  
            super(context);  
            this.context=context;
        }  
        public FixedSpeedScroller(Context context, Interpolator interpolator) {  
            super(context, interpolator);  
            this.context=context;
        } 
        /**
         *  设置改变ViewPager的滑动时间  
         * @param vp  ViewPager 对象
         * @param time  时间
         */
        public void setDuration(ViewPager vp,int time) {
             try {
                 Field field = ViewPager.class.getDeclaredField("mScroller");
                 field.setAccessible(true);
                 this.setmDuration(time);//设置翻动时间
                 field.set(vp, this);
             } catch (Exception e) {
    
             }
         } 
        @Override  
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {  
            //System.out.println("startScroll1");
            super.startScroll(startX, startY, dx, dy, mDuration);  
        }  
        @Override  
        public void startScroll(int startX, int startY, int dx, int dy) {  
            //System.out.println("startScroll2");
            super.startScroll(startX, startY, dx, dy, mDuration);  
        }  
        public void setmDuration(int time) {  
            mDuration = time;  
        }  
        public int getmDuration() {  
            return mDuration;  
        }  
    }

    4、编写MainActivity,测试组件

    public class MainActivity extends Activity {
        
        private MyImgScroll myPager; // 图片容器
        private LinearLayout ovalLayout; // 圆点容器
        private List<View> listViews; // 图片组
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            myPager = (MyImgScroll) findViewById(R.id.myvp);
            ovalLayout = (LinearLayout) findViewById(R.id.vb);
            InitViewPager();//初始化图片
            //开始滚动
            myPager.start(this, listViews, 4000, ovalLayout,
                    R.layout.ad_bottom_item, R.id.ad_item_v,
                    R.drawable.dot_focused, R.drawable.dot_normal);
        }
        @Override
        protected void onRestart() {
            myPager.startTimer();
            super.onRestart();
        }
        
        @Override
        protected void onStop() {
            myPager.stopTimer();
            super.onStop();
        }
        /**
         * 初始化图片
         */
        private void InitViewPager() {
            listViews = new ArrayList<View>();
            int[] imageResId = new int[] { R.drawable.banner1, R.drawable. banner2,
                    R.drawable. banner3, R.drawable.d, R.drawable. banner4 };
            for (int i = 0; i < imageResId.length; i++) {
                ImageView imageView = new ImageView(this);
                imageView.setOnClickListener(new OnClickListener() {
                    public void onClick(View v) {// 设置图片点击事件
                        Toast.makeText(MainActivity.this,
                                "点击了:" + myPager.getCurIndex(), Toast.LENGTH_SHORT)
                                .show();
                    }
                });
                imageView.setImageResource(imageResId[i]);
                imageView.setScaleType(ScaleType.CENTER_CROP);
                listViews.add(imageView);
            }
        }
    
    }

    5、MainActivity布局文件

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
        <com.jereh.view. MyScrollImageView
            android:id="@+id/myvp"
            android:layout_width="fill_parent"
            android:layout_height="120dp" />
        <LinearLayout
            android:id="@+id/vb"
            android:layout_width="match_parent"
            android:layout_height="10dp"
            android:layout_marginTop="3dip"
            android:gravity="center"
            android:orientation="horizontal" >
        </LinearLayout>
    </LinearLayout>

      完!

    作者:杰瑞教育
    出处:http://www.cnblogs.com/jerehedu/ 
    本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
     
  • 相关阅读:
    10 个深恶痛绝的 Java 异常。。
    为什么公司宁愿 25K 重新招人,也不给你加到 20K?原因太现实……
    推荐一款代码神器,代码量至少省一半!
    Spring Cloud Greenwich 正式发布,Hystrix 即将寿终正寝。。
    hdu 3853 LOOPS(概率 dp 期望)
    hdu 5245 Joyful(期望的计算,好题)
    hdu 4336 Card Collector(期望 dp 状态压缩)
    hdu 4405 Aeroplane chess(概率+dp)
    hdu 5036 Explosion(概率期望+bitset)
    hdu 5033 Building (单调栈 或 暴力枚举 )
  • 原文地址:https://www.cnblogs.com/jerehedu/p/4421428.html
Copyright © 2020-2023  润新知