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>

 

  完!

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。