viewpager实现图片轮播+小圆点跟着动

时间:2022-02-13 16:34:51

一、ViewPager简单用法

ViewPager的简单用法:

在布局文件中引入ViewPager,不记得完整的名称的话可以直接到support.v4.view包下找到ViewPager然后copy它的全路径名。

<android.support.v4.view.ViewPager
        android:id="@+id/guide_viewpager"
        android:layout_height="match_parent"
        android:layout_width="match_parent" 
        />

java代码中为ViewPager设置适配数据:设置list数据,设置adapteradapter要继承PagerAdapter,重写adaptergetCount()isViewFromObject(),instantiateItem(),destroyItem()四个方法。

private ArrayList<ImageView> guideList;
guideList=new ArrayList<ImageView>();
	   int imageid[]=new int []{
			   R.drawable.guide_1,
			   R.drawable.guide_2,
			   R.drawable.guide_3
	   };
	   ImageView iv;
for(int i=0;i<imageid.length;i++){
		   iv=new ImageView(this);
		   //设置图片资源
		   iv.setImageResource(imageid[i]);
		   //设置填充
		   iv.setScaleType(ScaleType.FIT_XY);
		   guideList.add(iv);
//给viewpager设置数据
	   viewpager.setAdapter(new guideAdapter());
   class guideAdapter extends PagerAdapter{
	@Override
	public int getCount() {
		if (guideList!=null) {
			return guideList.size();
		}
		return 0;
	}
	@Override
	public boolean isViewFromObject(View view, Object object) {
		return view==object;
	}
	@Override
	public Object instantiateItem(ViewGroup container, int position) {
		//1.获取imageview
		ImageView iv=guideList.get(position);
		//2.把imageview添加到viewpager
		container.addView(iv);
		//3.返回imageview
		return iv;
	}
	@Override
	public void destroyItem(ViewGroup container, int position, Object object) {
		container.removeView((View) object);
	}  
   }

二、点的动画移动

1.首先从布局上分析点的动画移动:

RelativeLayout位于父组件的底部,中间。里面有一个LinearLayout子控件水平摆放用于盛放静态的点,还有一个动态的View可以在代码中动态的设置它的MarginLeft属性来实现动画效果,并且移动到某个位置要遮盖掉LinearLayout里的静态点。

页面布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    <android.support.v4.view.ViewPager
        android:id="@+id/guide_viewpager"
        android:layout_height="match_parent"
        android:layout_width="match_parent" 
        />
<!-- 动态点的实现 -->
    <RelativeLayout 
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
         android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="25dp"
        >
    <!-- 在底部添加静态点 的容器-->
    <LinearLayout 
        android:id="@+id/guide_point_cont"
        android:orientation="horizontal"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        ></LinearLayout>
    <View 
        android:id="@+id/point_focus"
        android:layout_height="10dp"
        android:layout_width="10dp"
        android:background="@drawable/guide_point_focus" />
</RelativeLayout>
</RelativeLayout>

2.具体动画的实现逻辑,两个重点:测量----监听静态点容器布局是否完成,布局完成之后测量两个孩子的左边距之间的距离;监听---这里的监听是指监听ViewPageritem的滑动,根据ViewPageritem的滑动距离设置动态点的左边距。

完整代码如下:

public class GuideUI extends Activity implements OnPageChangeListener,OnClickListener{
	private ViewPager viewpager;
	private ArrayList<ImageView> guideList;
	//静态点容器
	private LinearLayout point_container;
	//动态点
	private View point_focus;
	//两个静态点之间的距离
	int point_space;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.guide);
		//初始化wiew
		initView();
		//初始化数据
		initData();
		
	}

	private void initView() {
		viewpager=(ViewPager) findViewById(R.id.guide_viewpager);
		point_container=(LinearLayout) findViewById(R.id.guide_point_cont);
		point_focus=findViewById(R.id.point_focus);	
		point_container.getViewTreeObserver().//监听布局完成
		addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
			
			@Override
			public void onGlobalLayout() {
				point_container.getViewTreeObserver().
				removeGlobalOnLayoutListener(this);
				//测量两个子类组件之间的距离
				point_space=point_container.getChildAt(1).getLeft()
						-point_container.getChildAt(0).getLeft();
				
			}
		});
		guide_start.setOnClickListener(this);
	}
   private void initData() {
	   guideList=new ArrayList<ImageView>();
	   int imageid[]=new int []{
			   R.drawable.guide_1,
			   R.drawable.guide_2,
			   R.drawable.guide_3
	   };
	   ImageView iv;
	   View point;
	   for(int i=0;i<imageid.length;i++){
		   iv=new ImageView(this);
		   //设置图片资源
		   iv.setImageResource(imageid[i]);
		   //设置填充
		   iv.setScaleType(ScaleType.FIT_XY);
		   guideList.add(iv);
		   //设置底部静态点
		   point=new View(this);
		   point.setBackgroundResource(R.drawable.guide_point_normal);
		   LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(30, 30);
		   if (i!=0) {
			   //这里的数值单位是px
			   params.leftMargin=20;	
		}
		   point_container.addView(point,params);	   
	   }
	   //给viewpager设置数据
	   viewpager.setAdapter(new guideAdapter());
	   //给viewpager设置监听
	   viewpager.setOnPageChangeListener(this);
	}
   class guideAdapter extends PagerAdapter{
	@Override
	public int getCount() {
		if (guideList!=null) {
			return guideList.size();
		}
		return 0;
	}
	@Override
	public boolean isViewFromObject(View view, Object object) {
		return view==object;
	}
	@Override
	public Object instantiateItem(ViewGroup container, int position) {
		//1.获取imageview
		ImageView iv=guideList.get(position);
		//2.把imageview添加到viewpager
		container.addView(iv);
		//3.返回imageview
		return iv;
	}
	@Override
	public void destroyItem(ViewGroup container, int position, Object object) {
		container.removeView((View) object);
	}  
   }
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {//positionOffset:滑动的百分比,滑动的距离/父容器的宽度,positionOffsetPixels:滑动的像素点
	//viewpager正在滚动时调用的方法
	int marginLeft=(int) (positionOffset*point_space+point_space*position+0.5f);
	RelativeLayout.LayoutParams params=(android.widget.RelativeLayout.LayoutParams) point_focus.getLayoutParams();
	params.leftMargin=marginLeft;
	point_focus.setLayoutParams(params);
}

@Override
public void onPageSelected(int position) {
	//viewpager被选中的时候调用的方法
	}

@Override
public void onPageScrollStateChanged(int state) {
	// 滚动状态改变的时候调用的方法
	
}
}

好了通过上面的的操作我们可以在滑动切换viewpager的图片的时候让下边的红色小圆点也跟着滑动(有在两个非选中点之间移动的过程)。

三、viewpager的自动轮播

轮播的逻辑:

class AutoSwitchPic extends Handler implements Runnable{
		public void start() {//控制轮播的开始
			stop();
            //发送一个延时执行的消息
			postDelayed(this, 2000);
		}
       public void stop() {//控制轮播的结束
            //从消息队列中移除消息
			removeCallbacks(this);
		}
		@Override
		public void run() {
            //获取当前的轮播位置
			int position=viewpager.getCurrentItem();
			if (position!=guideList.size()-1) {
                 //设置接下来的轮播位置
				viewpager.setCurrentItem(++position);	
			}
			else{
				viewpager.setCurrentItem(0);
			}
			postDelayed(this, 2000);
		}	
	}

在需要开启轮播的地方写:

private AutoSwitchPic autoSwitchPic;
if (autoSwitchPic==null) {
			autoSwitchPic=new AutoSwitchPic();
			autoSwitchPic.start();
		}

对于轮播过程中viewpager触摸事件的处理:

viewpager.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					autoSwitchPic.stop();
					break;
				case MotionEvent.ACTION_MOVE:
					break;
				case MotionEvent.ACTION_CANCEL:
				case MotionEvent.ACTION_UP:
					autoSwitchPic.start();
					break;
				default:
					break;
				}
				return false;
			}
		});