Android自定义控件3----继承ViewGroup自定义和系统一样的ViewPager

效果图:


项目结构:


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中
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();
       };
    }
}
工具类:MyScroller中:
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;
    }
}
源码下载:Myself----仿viewpager中 
http://download.csdn.net/download/zhaihaohao1/10111351
参考视频:
http://www.gulixueyuan.com/course/124/learn#lesson/1909







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值