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>

  完!

时间: 2024-10-11 01:35:59

Android实现图片轮显效果——自定义ViewPager控件的相关文章

ASP动态网页设计与Ajax技术----制作图片轮显效果

<!doctype html><html><head><meta charset="utf-8"><title>制作图片轮显效果</title></head><style type="text/css"> img{border: 0px;} .imgsBox{overflow: hidden; width: 282px; height: 176px;} .imgs a{d

图片轮显效果大全

综合各种效果的图片轮显 <SCRIPT language="VBScript">Dim FileList,FileListArr,TxtList,TxtListArrFileList = "http://et.21cn.com/portray/images/if/01.jpg,http://et.21cn.com/portray/images/if/02.jpg,http://et.21cn.com/portray/images/if/03.jpg"Tx

Android View measure (二) 自定义UI控件measure相关

本篇模拟三个角色:Android 架构师-小福.Android  控件开发工程师-小黑. Android 开发工程师-小白,下面按照三个角色不同角度分析measure过程. 小福负责分享: measure的本质 measure代码流程 onMeasure方法与MeasureSpec 提出问题 小黑负责分享: 布局控件开发中覆写Measure例子 - ok 从遇到的一个异常说起 什么时候需要覆写onMeaure? - ok view.getWidth与view.getMeasureWidth区别

自定义Gallery控件实现简单3D图片浏览器

本篇文章主要介绍如何使用自定义的Gallery控件,实现3D效果的图片浏览器的效果. 话不多说,先看效果. 上面是一个自定义的Gallery控件,实现倒影和仿3D的效果,下面是一个图片查看器,点击上面的小图片,可以在下面查看大图片. 下面重点说一下,实现图片查看器的思路. 1.手机中图片路径的获取 首先,先不管图片如何展示,如果我们想实现图片查看器的功能,我们首先需要做的是获取到所有的图片的路径信息,只有这样,我们才能实现对图片的查看. 我们可以使用下面的代码实现 private List<St

Android自定义组合控件--图片加文字,类似视频播放软件的列表

分四步来写: 1,组合控件的xml; 2,自定义组合控件的属性; 3,自定义继承组合布局的class类,实现带两参数的构造器; 4,在xml中展示组合控件. 具体实现过程: 一.组合控件的xml 我接触的有两种方式,一种是普通的Activity的xml:一种是父节点为merge的xml.我项目中用的是第一种,但个人感觉第二种好,因为第一种多了相对或者绝对布局层. 我写的 custom_pictext.xml <?xml version="1.0" encoding="u

CSS3图片轮播效果

原文:CSS3图片轮播效果 在网页中用到图片轮播效果,单纯的隐藏.显示,那再简单不过了,要有动画效果,如果是自己写的话(不用jquery等),可能要费点时间.css3的出现,让动画变得不再是问题,而且简单易用.下面介绍我用css3与js写的一个图片轮播效果. 一般图片轮播就是三四张图片: <div class="wrap"> <div class="carousel"> <div><img src="http://

js实现淘宝首页图片轮播效果

原文:http://ce.sysu.edu.cn/hope2008/Education/ShowArticle.asp?ArticleID=10585 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>淘宝首页图片轮播效果</title> <style> <!-- * {margin: 0;padding:0;} body

jQuery个性化图片轮播效果

购物产品展示:图片轮播器<效果如下所示> 思路说明: 每隔一段时间,实现图片的自动切换及选项卡选中效果 两个区域:   最外层容器区域,如上图红色线框矩形   选项卡区域 两个事件:    鼠标悬浮或鼠标划入mouseover    鼠标离开mouseleave /**大屏广告滚动样式**/ 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF

首页图片轮播效果

<html><head><meta  charset="utf-8" /><title>首页图片轮播效果</title><style type="text/css">* {margin: 0;padding:0;}body {background: #222;}ol{list-style: none;}img {border: 0 none;}#slider { border: 1px soli