效果图:
项目结构:
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<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.viewpager.MainActivity">
<com.example.viewpager.MyViewPager
android:id="@+id/myviewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
MainActivity中
package com.example.viewpager; import android.app.Activity; import android.os.Bundle; import android.view.Window; import android.widget.ImageView; public class MainActivity extends Activity { private MyViewPager myviewpager; private int[] ids = {R.drawable.a1, R.drawable.a2, R.drawable.a3, R.drawable.a4, R.drawable.a5, R.drawable.a6}; @Override protected void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题 super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myviewpager = (MyViewPager) findViewById(R.id.myviewpager); //添加页面 for (int i = 0; i < ids.length; i++) { ImageView imageView = new ImageView(this); imageView.setBackgroundResource(ids[i]); //添加到MyViewPager这个View中 myviewpager.addView(imageView); } } }
MyViewPager中
工具类:MyScroller中:package com.example.viewpager; import android.content.Context; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; /** * 作者:杨光福 on 2016/5/16 10:33 * 微信:yangguangfu520 * QQ号:541433511 * 作用:仿ViewPager */ public class MyViewPager extends ViewGroup { /** * 手势识别器 * 1.定义出来 * 2.实例化-把想要的方法给重写 * 3.在onTouchEvent()把事件传递给手势识别器 * */ private GestureDetector detector; /** * 当前页面的下标位置 */ private int currentIndex; private MyScroller scroller; /** * 构造方法 */ public MyViewPager(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } private void initView(final Context context) { scroller = new MyScroller(); //2.实例化手势识别器 detector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){ @Override public void onLongPress(MotionEvent e) { super.onLongPress(e); Toast.makeText(context,"长按", Toast.LENGTH_SHORT).show(); } /** * * @param e1 * @param e2 * @param distanceX 在X轴滑动了的距离 * @param distanceY 在Y轴滑动了的距离 * @return */ @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { /** *x:要在X轴移动的距离 *y:要在Y轴移动的距离 */ scrollBy((int)distanceX,0); return true; } @Override public boolean onDoubleTap(MotionEvent e) { Toast.makeText(context,"双击", Toast.LENGTH_SHORT).show(); return super.onDoubleTap(e); } }); } /** * 制定控件位置(子控件的位置) * @param changed * @param l * @param t * @param r * @param b */ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { //遍历孩子,给每个孩子指定在屏幕的坐标位置 for(int i=0;i<getChildCount();i++){ View childView = getChildAt(i); childView.layout(i*getWidth(),0,(i+1)*getWidth(),getHeight()); } } private float startX; /** * 触摸事件 */ @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); //3.把事件传递给手势识别器 detector.onTouchEvent(event); switch (event.getAction()){ case MotionEvent.ACTION_DOWN: //1.记录坐标 startX = event.getX(); break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: //2.来到新的坐标 float endX = event.getX(); //下标位置 int tempIndex = currentIndex; if((startX-endX)>getWidth()/2){ //显示下一个页面 tempIndex ++; }else if((endX-startX)>getWidth()/2){ //显示上一个页面 tempIndex --; } //根据下标位置移动到指定的页面 scrollToPager(tempIndex); break; } return true; } /** * 屏蔽非法值,根据位置移动到指定页面 * @param tempIndex */ private void scrollToPager(int tempIndex) { if(tempIndex < 0){ tempIndex = 0; } if(tempIndex > getChildCount()-1){ tempIndex = getChildCount()-1; } //当前页面的下标位置 currentIndex = tempIndex; int distanceX = currentIndex*getWidth() - getScrollX(); //移动到指定的位置 // scrollTo(currentIndex*getWidth(),getScrollY()); scroller.startScroll(getScrollX(),getScrollY(),distanceX,0); // invalidate();;//onDraw();computeScroll(); } @Override public void computeScroll() { // super.computeScroll(); if( scroller.cuputeScrollOffset()){ float currX = scroller.getCurrX(); scrollTo((int) currX,0); invalidate(); }; } }
源码下载:Myself----仿viewpager中package com.example.viewpager; import android.os.SystemClock; /** * 作者:杨光福 on 2016/5/16 11:54 * 微信:yangguangfu520 * QQ号:541433511 * 作用:xxxx */ public class MyScroller { /** * X轴的起始坐标 */ private float startY; /** * Y轴的起始坐标 */ private float startX; /** * 在X轴要移动的距离 */ private int distanceX; /** * 在Y轴要移动的距离 */ private int distanceY; /** 开始的时间 */ private long startTime; /** * 总时间 */ private long totalTime = 500; /** * 是否移动完成 * false没有移动完成 * true:移动结束 */ private boolean isFinish; private float currX; /** * 得到坐标 */ public float getCurrX() { return currX; } public void startScroll(float startX, float startY, int distanceX, int distanceY) { this.startY = startY; this.startX = startX; this.distanceX = distanceX; this.distanceY = distanceY; this.startTime = SystemClock.uptimeMillis();//系统开机时间 this.isFinish = false; } /** * 速度 求移动一小段的距离 求移动一小段对应的坐标 求移动一小段对应的时间 true:正在移动 false:移动结束 * @return */ public boolean cuputeScrollOffset(){ if(isFinish){ return false; } long endTime = SystemClock.uptimeMillis(); //这一小段所花的时间 long passTime = endTime - startTime; if(passTime < totalTime){ //还没有移动结束 //计算平均速度 // float voleCity = distanceX/totalTime; //移动这个一小段对应的距离 float distanceSamllX = passTime* distanceX/totalTime; currX = startX + distanceSamllX; }else{ //移动结束 isFinish =true; currX = startX + distanceX; } return true; } }
http://download.csdn.net/download/zhaihaohao1/10111351参考视频:http://www.gulixueyuan.com/course/124/learn#lesson/1909