Android实现图片轮显效果——自定义ViewPager控件
ybny
10年前
一、问题概述 |
使用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://blog.csdn.net/jerehedu/article/details/45196019