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>
Android学习Scroller(二),布布扣,bubuko.com
时间: 2024-10-23 03:52:53