首页 > 代码库 > Android学习Scroller(二)

Android学习Scroller(二)

MainActivity如下:

package cc.testscroller1;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.Scroller;
/**
 * Demo描述:
 * 学习Scroller类(原理篇)
 * 
 * 原理分析:
 * 点击Button的背景将发生变化,这时button将调用invalidate()请求重绘,
 * 这就是View系统重绘的源头,即scroll动态效果的触发者.
 * 既然重绘请求已发出,那么整个View系统就会进行一次自上而下的绘制.
 * 所以先OuterLinearLayout重绘,然后InnerLinearLayout,最后是自定义的Button.
 * 但在InnerLinearLayout中又执行了scrollTo(),这会导致Button的重绘.
 * 于是又开始至上而下的重绘,该过程会一直进行下去,直到mScroller.computeScrollOffset()
 * 返回false.
 * 
 * 
 * 测试说明:
 * 测试时可分别注释掉第149和185行观察效果
 * 
 * 
 * 备注说明:
 * 1 关于方法startScroll(int startX, int startY, int dx, int dy, int duration)
 *   第一个参数:开始滑动的X位置
 *   第二个参数:开始滑动的Y位置
 *   第三个参数:X方向滑动的距离,正数向左,负数向右
 *   第四个参数:Y方向滑动的距离,正数向上,负数向下
 *   第五个参数:滑动持续的时间
 *   
 *   该方法只是一个Scroll的行为模型(见参考资料6).它只是为Scroll这个行为设置了一些
 *   属性而已.有时看到这个方法的名字startScroll()以为它就是用来控制和启动滑动.
 *   其实不是的,真正用来滑动的是下面这个方法scrollTo(int x, int y).
 *   虽然它不是用来实际滑动的,但是可以在其它地方取得该方法中设置的这些属性.
 *   比如  mScroller.getCurrX()或者mScroller.getDuration()等等
 *   
 * 2 关于方法scrollTo(int x, int y)
 *   Set the scrolled position of your view
 *   它才是将View滑动到指定的位置进行显示
 *   
 * 3 关于方法computeScrollOffset()
 *    If it returns true, the animation is not yet finished. 
 *    返回值为boolean类型true说明滚动尚未完成,false说明滚动已完成
 *    该方法通常放在computeScroll()中用来判断是否滚动是否结束
 *   
 * 
 * 参考资料:
 * 1 http://blog.csdn.net/gemmem/article/details/7321910
 * 2 http://gundumw100.iteye.com/blog/1884373
 * 3 http://ipjmc.iteye.com/blog/1615828
 * 4 http://blog.csdn.net/c_weibin/article/details/7438323
 * 5 http://www.cnblogs.com/wanqieddy/archive/2012/05/05/2484534.html
 * 6 http://blog.csdn.net/hudashi/article/details/7353075
 * 
 *   Thank you very much
 */
public class MainActivity extends Activity {
	private OuterLinearLayout mOuterLinearLayout;
	private InnerLinearLayout mInnerLinearLayout1;
	private InnerLinearLayout mInnerLinearLayout2;
    private Scroller mScroller;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        mScroller = new Scroller(this);
        
        //OuterLinearLayout是最外层的LinearLayout
        mOuterLinearLayout = new OuterLinearLayout(this);
        mOuterLinearLayout.setOrientation(LinearLayout.VERTICAL);
        LayoutParams outerLinearLayoutLayoutParams = 
        new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);    
        this.setContentView(mOuterLinearLayout, outerLinearLayoutLayoutParams);
        
        //InnerLinearLayout内层的第一个LinearLayout
        mInnerLinearLayout1 = new InnerLinearLayout(this);
        mInnerLinearLayout1.setBackgroundColor(Color.parseColor("#ff0033"));
        LayoutParams innerLinearLayoutLayoutParams1 = 
        new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);    
        innerLinearLayoutLayoutParams1.weight=1;
        mOuterLinearLayout.addView(mInnerLinearLayout1,innerLinearLayoutLayoutParams1);
        
        
        //InnerLinearLayout内层的第二个LinearLayout
        mInnerLinearLayout2 = new InnerLinearLayout(this);
        mInnerLinearLayout2.setBackgroundColor(Color.parseColor("#0000cc"));
        LayoutParams innerLinearLayoutLayoutParams2 = 
        new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);    
        innerLinearLayoutLayoutParams2.weight=1;
        mOuterLinearLayout.addView(mInnerLinearLayout2,innerLinearLayoutLayoutParams2);

        
        //为第一个LinearLayout添加一个Button
        ButtonSubClass buttonSubClass1 = new ButtonSubClass(this);
        buttonSubClass1.setText("Button1 in LinearLayout1");
        buttonSubClass1.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
            	   //参见上方的备注说明1
                   mScroller.startScroll(20, 20, -200, -200, 1000);
                }
        });
        mInnerLinearLayout1.addView(buttonSubClass1);
        
        
        
        //为第二个LinearLayout添加一个Button
        ButtonSubClass buttonSubClass2 = new ButtonSubClass(this);
        buttonSubClass2.setText("Button2 in LinearLayout2");
        buttonSubClass2.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
            	    //参见上方的备注说明1
                    mScroller.startScroll(20, 20, -200, -200, 1000);
                }
        });
        mInnerLinearLayout2.addView(buttonSubClass2);
        
    }

	

	class OuterLinearLayout extends LinearLayout {
		public OuterLinearLayout(Context context) {
			super(context);
		}
		
		@Override
		protected void onDraw(Canvas canvas) {
			super.onDraw(canvas);
			System.out.println("OuterLinearLayout---> onDraw()");
		}
		
		@Override
		public void computeScroll() {
			    //参见上方的备注说明3
			if (mScroller.computeScrollOffset()){
				
				//参见上方的备注说明2
				scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
				System.out.println("OuterLinearLayout---> computeScroll()");
				
				//System.out.println("InnerLinearLayout computeScroll()---> CurrX()="
				                   // +mScroller.getCurrX()+",CurrY="+mScroller.getCurrY()+
				                   // ",StartX()="+mScroller.getStartX()+",StartY="+mScroller.getStartY());
				
			}
		}

		@Override
		protected void dispatchDraw(Canvas canvas) {
			super.dispatchDraw(canvas);
			System.out.println("OuterLinearLayout --->dispatchDraw()");
		}
	}
	
	
	
	class InnerLinearLayout extends LinearLayout {
		public InnerLinearLayout(Context context) {
			super(context);
		}
		
		@Override
		protected void onDraw(Canvas canvas) {
			super.onDraw(canvas);
			System.out.println("InnerLinearLayout---> onDraw()");
		}

		@Override
		public void computeScroll() {
			    //参见上方的备注说明3
			if (mScroller.computeScrollOffset()){
				
				//参见上方的备注说明2
				scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
				System.out.println("InnerLinearLayout---> computeScroll()");
				
				//System.out.println("InnerLinearLayout computeScroll()---> CurrX()="
				                   // +mScroller.getCurrX()+",CurrY="+mScroller.getCurrY()+
				                   // ",StartX()="+mScroller.getStartX()+",StartY="+mScroller.getStartY());
				
			}
		}
	}
	
	
	class ButtonSubClass extends Button {
		public ButtonSubClass(Context context) {
			super(context);
		}

		@Override
		protected void onDraw(Canvas canvas) {
			super.onDraw(canvas);
			System.out.println("ButtonSubClass---> onDraw()");
		}
	}
	
}


main.xml如下:

<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" >

</RelativeLayout>