第一步:用viewpager实现滑动。
首先是页面布局fragment_home.xml,只定义了一个Viewpager,代码如下:
<RelativeLayout 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" tools:context="com.example.wmk.fragment.HomeFragment"> <android.support.v4.view.ViewPager android:id="@+id/vp_homeFragment" android:layout_width="match_parent" android:layout_height="180dp" /> </RelativeLayout>
接着是,主界面fragment,主界面,只是为ViewPager 做了个适配器而已。
package com.example.wmk.fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import com.example.wmk.R; /** * HomeFragment */ public class HomeFragment extends Fragment { private int[] mImageIds = {R.mipmap.op01, R.mipmap.op02, R.mipmap.op03, R.mipmap.op04, R.mipmap.op05 }; /** * 首页布局容器 */ private View homeLayout; /** * ViewPager */ private ViewPager vpHomeFragment; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { homeLayout = inflater.inflate(R.layout.fragment_home, container, false); //初始化 initViews(); //设置适配器 vpHomeFragment.setAdapter(new MyViewPagerAdapter()); return homeLayout; } private void initViews() { vpHomeFragment = (ViewPager) homeLayout.findViewById(R.id.vp_homeFragment); } class MyViewPagerAdapter extends PagerAdapter { @Override public int getCount() { /** * 返回图片的数量 * 如果要使viewpager循环,直接返回比mImageIds.length大的值就可以了 */ return mImageIds.length; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { ImageView imageView = new ImageView(getActivity()); imageView.setBackgroundResource(mImageIds[position]); container.addView(imageView); return imageView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } } }
mImageIds数组里面存放了5张的图片,用于实现图片轮播。 Viewpager滑动效果如下:
下面对第一步中的代码进行了改进,主要对MyViewPagerAdapter进行了封装,代码如下:
package com.example.wmk.adapter; import android.content.Context; import android.support.v4.view.PagerAdapter; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; /** * Created by 老王 on 2016/12/15. */ public class MyViewPagerAdapter extends PagerAdapter { /** * 上下文 */ private Context context; /** * 图片数组 */ private int[] mImageIds; public MyViewPagerAdapter(Context context, int[] mImageIds) { this.context = context; this.mImageIds = mImageIds; } @Override public int getCount() { /** * 返回图片的数量 * 如果要使viewpager循环,直接返回比mImageIds.length大的值就可以了 */ return mImageIds.length; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { ImageView imageView = new ImageView(context); imageView.setBackgroundResource(mImageIds[position]); container.addView(imageView); return imageView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } }
想对应,主界面的代码如下:
package com.example.wmk.fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import com.example.wmk.R; import com.example.wmk.adapter.MyViewPagerAdapter; /** * HomeFragment */ public class HomeFragment extends Fragment { private int[] mImageIds = {R.mipmap.op01, R.mipmap.op02, R.mipmap.op03, R.mipmap.op04, R.mipmap.op05 }; /** * 首页布局容器 */ private View homeLayout; /** * ViewPager */ private ViewPager vpHomeFragment; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { homeLayout = inflater.inflate(R.layout.fragment_home, container, false); //初始化 initViews(); //设置适配器 vpHomeFragment.setAdapter(new MyViewPagerAdapter(getActivity(), mImageIds)); return homeLayout; } private void initViews() { vpHomeFragment = (ViewPager) homeLayout.findViewById(R.id.vp_homeFragment); }
第二步:实现滑动的过程中,对应的游标图片跟随滑动。
首先是,主界面布局的代码,相对应的变化如下:
<RelativeLayout 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" tools:context="com.example.wmk.fragment.HomeFragment"> <android.support.v4.view.ViewPager android:id="@+id/vp_homeFragment" android:layout_width="match_parent" android:layout_height="180dp" /> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="160dp" android:gravity="center"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1.0" android:src="@mipmap/shape_point_unselector" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1.0" android:src="@mipmap/shape_point_unselector" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1.0" android:src="@mipmap/shape_point_unselector" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1.0" android:src="@mipmap/shape_point_unselector" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1.0" android:src="@mipmap/shape_point_unselector" /> </LinearLayout> <ImageView android:id="@+id/cur_dot" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/shape_point_selector" /> </FrameLayout> </RelativeLayout>
布局效果图,如下:
其次,主界面代码如下:
package com.example.wmk.fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.animation.TranslateAnimation; import android.widget.ImageView; import com.example.wmk.R; import com.example.wmk.adapter.MyViewPagerAdapter; /** * HomeFragment */ public class HomeFragment extends Fragment { private int[] mImageIds = {R.mipmap.op01, R.mipmap.op02, R.mipmap.op03, R.mipmap.op04, R.mipmap.op05 }; /** * 首页布局容器 */ private View homeLayout; /** * ViewPager */ private ViewPager vpHomeFragment; /** * */ private ImageView curDot; // 位移量 private int offset; // 记录当前的位置 private int curPos = 0; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { homeLayout = inflater.inflate(R.layout.fragment_home, container, false); //初始化 initViews(); //设置适配器 vpHomeFragment.setAdapter(new MyViewPagerAdapter(getActivity(), mImageIds)); vpHomeFragment.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { int pos = position % mImageIds.length; moveCursorTo(pos); curPos = pos; } @Override public void onPageScrollStateChanged(int state) { } }); return homeLayout; } /** * 移动指针到相邻的位置 * * @param position 指针的索引值 */ private void moveCursorTo(int position) { TranslateAnimation anim = new TranslateAnimation(offset * curPos, offset * position, 0, 0); anim.setDuration(30); anim.setFillAfter(true); curDot.startAnimation(anim); } private void initViews() { vpHomeFragment = (ViewPager) homeLayout.findViewById(R.id.vp_homeFragment); curDot = (ImageView) homeLayout.findViewById(R.id.cur_dot); curDot.getViewTreeObserver().addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { offset = curDot.getWidth(); return true; } }); } }
效果图如下:
下面对第二步中的主界面代码就行优化,代码如下:
package com.example.wmk.connector; import android.support.v4.view.ViewPager; /** * Created by 老王 on 2016/12/15. */ public class MyPageChangeListener implements ViewPager.OnPageChangeListener { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { } }
package com.example.wmk.fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.animation.TranslateAnimation; import android.widget.ImageView; import com.example.wmk.R; import com.example.wmk.adapter.MyViewPagerAdapter; import com.example.wmk.connector.MyPageChangeListener; /** * HomeFragment */ public class HomeFragment extends Fragment { /** * 首页布局容器 */ private View homeLayout; /** * ViewPager */ private ViewPager vpHomeFragment; /** * ImageView */ private ImageView curDot; // 位移量 private int offset; // 记录当前的位置 private int curPos = 0; // 图片数组 private int[] mImageIds = {R.mipmap.op01, R.mipmap.op02, R.mipmap.op03, R.mipmap.op04, R.mipmap.op05 }; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { homeLayout = inflater.inflate(R.layout.fragment_home, container, false); //初始化 initViews(); //监听事件 initEvents(); //设置适配器 initSetAdapter(); return homeLayout; } private void initViews() { vpHomeFragment = (ViewPager) homeLayout.findViewById(R.id.vp_homeFragment); curDot = (ImageView) homeLayout.findViewById(R.id.cur_dot); } private void initEvents() { /** * ViewPager监听事件 */ vpHomeFragment.addOnPageChangeListener(new MyPageChangeListener() { @Override public void onPageSelected(int position) { int pos = position % mImageIds.length; moveCursorTo(pos); curPos = pos; } }); /** * 游标图片监听事件 */ curDot.getViewTreeObserver().addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { offset = curDot.getWidth(); return true; } }); } private void initSetAdapter() { vpHomeFragment.setAdapter(new MyViewPagerAdapter(getActivity(), mImageIds)); } /** * 移动指针到相邻的位置 * * @param position 指针的索引值 */ private void moveCursorTo(int position) { TranslateAnimation anim = new TranslateAnimation(offset * curPos, offset * position, 0, 0); anim.setDuration(30); anim.setFillAfter(true); curDot.startAnimation(anim); } }
第三步,实现图片手动轮播。
主要就是对适配器进行修改,代码如下:
package com.example.wmk.adapter; import android.content.Context; import android.support.v4.view.PagerAdapter; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; /** * Created by 老王 on 2016/12/15. */ public class MyViewPagerAdapter extends PagerAdapter { /** * 上下文 */ private Context context; /** * 图片数组 */ private int[] mImageIds; public MyViewPagerAdapter(Context context, int[] mImageIds) { this.context = context; this.mImageIds = mImageIds; } @Override public int getCount() { /** * 返回图片的数量 * 如果要使viewpager循环,直接返回比mImageIds.length大的值就可以了 */ return Integer.MAX_VALUE; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { int pos = position % mImageIds.length; ImageView imageView = new ImageView(context); imageView.setBackgroundResource(mImageIds[pos]); container.addView(imageView); return imageView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } }
第四步,实现图片的自动轮播。通过handler发送一条延时消息机制,实现图片自动轮播,代码如下:
package com.example.wmk.fragment; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.app.Fragment; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.animation.TranslateAnimation; import android.widget.ImageView; import com.example.wmk.R; import com.example.wmk.adapter.MyViewPagerAdapter; import com.example.wmk.connector.MyPageChangeListener; /** * HomeFragment */ public class HomeFragment extends Fragment { /** * 首页布局容器 */ private View homeLayout; /** * ViewPager */ private ViewPager vpHomeFragment; /** * ImageView */ private ImageView curDot; // 位移量 private int offset; // 记录当前的位置 private int curPos = 0; // 图片数组 private int[] mImageIds = {R.mipmap.op01, R.mipmap.op02, R.mipmap.op03, R.mipmap.op04, R.mipmap.op05 }; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { homeLayout = inflater.inflate(R.layout.fragment_home, container, false); //初始化 initViews(); //监听事件 initEvents(); //设置适配器 initSetAdapter(); //发送消息 initSendMessage(); return homeLayout; } private void initViews() { vpHomeFragment = (ViewPager) homeLayout.findViewById(R.id.vp_homeFragment); curDot = (ImageView) homeLayout.findViewById(R.id.cur_dot); } private void initEvents() { /** * ViewPager监听事件 */ vpHomeFragment.addOnPageChangeListener(new MyPageChangeListener() { @Override public void onPageSelected(int position) { int pos = position % mImageIds.length; moveCursorTo(pos); curPos = pos; } }); /** * 游标图片监听事件 */ curDot.getViewTreeObserver().addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { offset = curDot.getWidth(); return true; } }); } private void initSetAdapter() { vpHomeFragment.setAdapter(new MyViewPagerAdapter(getActivity(), mImageIds)); } private void initSendMessage() { //延时两秒发送消息 mHandler.sendEmptyMessageDelayed(0, 2000); } /** * 移动指针到相邻的位置 * * @param position 指针的索引值 */ private void moveCursorTo(int position) { TranslateAnimation anim = new TranslateAnimation(offset * curPos, offset * position, 0, 0); anim.setDuration(30); anim.setFillAfter(true); curDot.startAnimation(anim); } /** * 广告条的自动轮播效果,将页面自动切换到下一个页面 * 实现方法之一:可以利用handler发送一条延时消息 * 实现方法之二:可以利用定时器 */ private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { int currentItem = vpHomeFragment.getCurrentItem();//获取viewPager当前页面的位置 vpHomeFragment.setCurrentItem(++currentItem); //继续发送延时两秒的消息,类似递归的效果,使广告一直切换 mHandler.sendEmptyMessageDelayed(0, 2000); /** * 当用户触摸的时候,自动轮播就应该停止下来 */ vpHomeFragment.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mHandler.removeCallbacksAndMessages(null); break; case MotionEvent.ACTION_UP: mHandler.sendEmptyMessageDelayed(0, 2000); break; default: break; } /** * 如果这里返回true,viewPager的事件将会被消耗掉,ViewPager将会响应不了 * 所以这里要返回false,让viewPager原生的触摸效果正常运行 */ return false; } }); } }; }