首页 > 代码库 > Android-Scroller

Android-Scroller

技术分享
播放幻灯片 全部下载
技术分享技术分享   

/********************SpriteLayout.java**********************************/

package com.example.game;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.View.MeasureSpec;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.Toast;

public class SpriteLayout extends ViewGroup {
    private float startX;
    private int curL=1;
    private int destL;
    VelocityTracker velocity=null;
    @Override
    public void computeScroll() {
        super.computeScroll();
        if(mScroller.computeScrollOffset()){
            scrollTo(mScroller.getCurrX(), 0);
            postInvalidate();
        }
    }
    public void startMove(){
        //从开(startX,startY)点开始滑动到(startX+deltaX,startY+deltaY)点,如果终点在起点的左边或这下边,便会向左或向下滑动,如果在邮编或者上边便会向右或向上滑动
        //起点和终点都是以view的左上角的坐标
        mScroller.startScroll((curL-1)*getWidth(), 0, getWidth(), 0,3000);
        curL++;
        if(curL>=3)
            curL=1;
        invalidate();
    }
    private Scroller mScroller;
    private float minDist;
    private void init(){
        mScroller=new Scroller(getContext());
        LinearLayout l1=new LinearLayout(getContext());
        l1.setBackgroundColor(Color.BLUE);
       
        LinearLayout l2=new LinearLayout(getContext());
        l2.setBackgroundColor(Color.CYAN);
        LinearLayout l3=new LinearLayout(getContext());
        l3.setBackgroundColor(Color.RED);
       
        this.addView(l1);
        this.addView(l2);
        this.addView(l3);
        minDist=ViewConfiguration.get(getContext()).getScaledEdgeSlop();
    }
    public SpriteLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
        init();
    }

    public SpriteLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        init();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
       
        // TODO Auto-generated method stub
       
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        //Toast.makeText(getContext(), "SpriteLayout touchevent"+event.getAction()+"return:"+super.onTouchEvent(event), Toast.LENGTH_SHORT).show();
        if(velocity==null){
            velocity = VelocityTracker.obtain();
        }
        velocity.addMovement(event);
        switch(event.getAction())
        {
        case MotionEvent.ACTION_DOWN:
            startX=event.getX();
            break;
        case MotionEvent.ACTION_MOVE:
            int delta=(int)(startX-event.getX());
            scrollBy(delta, 0);
            startX=event.getX();
            break;
        case MotionEvent.ACTION_UP:
            //如果手指从左向右滑动velocity.getXVelocity()返回正数
            //如果手指从右向左滑动velocity.getXVelocity()返回负数
            velocity.computeCurrentVelocity(1000);//一秒钟划过多少个像素,原本的基本单位是一毫秒划过多少个像素

            //getScrollX()就是viewgroup的左上角对应的视图的X坐标,当滑动的距离超过半屏的距离就当滑到下一屏,否则就是滑到当前屏
           
            int dest=(getScrollX()+getWidth()/2)/getWidth();
            //显示第N屏 scrollTo((N-1)*getWidth(),0)  startScroll(getScrollX(),0,(N-1)*getWidth()-getScrollX(),0)
            if(dest>getChildCount()-1){
                dest=getChildCount()-1;//滑到最后一个view 最后显示到viewgroup的左上角的X坐标为 (getChildCount()-1)*getWidth()而不是(getChildCount())*getWidth()
            }
            mScroller.startScroll(getScrollX(),0,(int) (dest*getWidth()-getScrollX()),0);
            invalidate();
            curL=dest;
            break;
        default:
            break;
        }

        return true;
    }

    public SpriteLayout(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        init();
    }

    // measure过程
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {


        // 设置该ViewGroup的大小
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(width, height);

        int childCount = getChildCount();

        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            // 设置每个子视图的大小 , 即全屏
            child.measure(getWidth(), getHeight());
        }
    }

    // layout过程
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
   
        int startLeft = 0; // 每个子视图的起始布局坐标
        int startTop = 0; // 间距设置为10px 相当于 android:marginTop= "10px"
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
           
            //即使可见的,才划到屏幕上
            if(child.getVisibility() != View.GONE)
                //左上角的X,Y  右下角的X,Y
                child.layout(startLeft, startTop,
                       startLeft + getWidth(),
                       startTop + getHeight() );
               
                startLeft = startLeft + getWidth() ; //校准每个子View的起始布局位置
                //三个子视图的在屏幕中的分布如下 [0 , 320] / [320,640] / [640,960]
        }
    }
}

/********************SpriteB.java**********************************/

package com.example.game;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;
import android.widget.Toast;

public class SpriteB extends Button {

    @Override
    public void computeScroll() {
        // TODO Auto-generated method stub
        super.computeScroll();
    }


    public SpriteB(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public SpriteB(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public SpriteB(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

}

/********************SpriteActivity.java**********************************/

package com.example.game;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;

public class SpriteActivity extends Activity {
    SpriteB sprite;
    SpriteLayout layout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
       
        setContentView(R.layout.main);
        sprite=(SpriteB) findViewById(R.id.btn);
        layout=(SpriteLayout) findViewById(R.id.layout);
        sprite.setOnClickListener(new OnClickListener() {
           
            @Override
            public void onClick(View v) {
                layout.startMove();
            }
        });
    }

}

/********************main.xml**********************************/

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
   
    <com.example.game.SpriteB
        android:id="@+id/btn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="this is a sprite button!"/>
    <com.example.game.SpriteLayout
        android:id="@+id/layout"
         android:layout_width="match_parent"
         android:layout_height="match_parent"/>
</LinearLayout>

Android-Scroller