一、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数据,设置adapter,adapter要继承PagerAdapter,重写adapter的getCount(),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.具体动画的实现逻辑,两个重点:测量----监听静态点容器布局是否完成,布局完成之后测量两个孩子的左边距之间的距离;监听---这里的监听是指监听ViewPager里item的滑动,根据ViewPager中item的滑动距离设置动态点的左边距。
完整代码如下:
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; } });