你的位置:首页 > 操作系统

[操作系统]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 @param ovalLayoutItemId   *      ovalLayout为空时 写0,圆点layout @param focusedId   *      ovalLayout为空时 写0, 圆点layout @param normalId   *      ovalLayout为空时 写0, 圆点layout */  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 ="http://schemas.android.com/apk/res/android"  ="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>

 

  完!