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>

Android学习Scroller(二),布布扣,bubuko.com

时间: 2024-08-08 09:37:58

Android学习Scroller(二)的相关文章

Android学习Scroller(二)——ViewGroup调用scrollTo()

MainActivity如下: package cc.ac; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.app.Activity; /** * Demo描述: * 对ViewGroup调用sc

Android学习Scroller(四)——实现拉动后回弹的布局

MainActivity如下: package cc.testscroller2; import android.os.Bundle; import android.app.Activity; /** * Demo描述: * 实现可以拉动后回弹的布局. * 类似于下拉刷新的. * * 参考资料: * 1 http://gundumw100.iteye.com/blog/1884373 * 2 http://blog.csdn.net/gemmem/article/details/7321910

Android学习Scroller(三)——控件平移划过屏幕 (Scroller简单使用)

MainActivity如下: package cc.cn; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.app.Activity; /** * Demo描述: * Scroller使用示例--让控件平移划过屏幕 * * 参考资料: * http://blog.cs

Android学习Scroller(三)

MainActivity如下: package cc.testscroller2; import android.os.Bundle; import android.app.Activity; /** * Demo描述: * 实现可以拉动后回弹的布局. * 类似于下拉刷新的. * * 参考资料: * 1 http://gundumw100.iteye.com/blog/1884373 * 2 http://blog.csdn.net/gemmem/article/details/7321910

Android学习Scroller(五)——详解Scroller调用过程以及View的重绘

MainActivity如下: package cc.ww; import android.os.Bundle; import android.widget.ImageView; import android.widget.ImageView.ScaleType; import android.widget.RelativeLayout; import android.widget.RelativeLayout.LayoutParams; import android.app.Activity;

Android学习Scroller(一)——View调用scrollTo()的理解及使用

MainActivity如下: package cc.uu; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.app.Activity; /** * Demo描述: * scrollTo()和scrollB

Android学习笔记二十九之SwipeRefreshLayout、RecyclerView和CardView

Android学习笔记二十九之SwipeRefreshLayout.RecyclerView和CardView 前面我们介绍了AlertDialog和几个常用的Dialog,ProgressDialog进度条提示框.DatePickerDialog日期选择对话框和TimePickerDialog时间选择对话框.这一节我们介绍几个新的API控件SwipeRefreshLayout.RecyclerView和CardView,这几个API控件都是google在Android5.0推出的.下面我们来学

Android学习笔记二

17. 在ContentProvider中定义的getType()方法是定义URI的内容类型. 18. SQLiteDatabase类中的insert/delete/update/query方法其实也挺好用的,我在EquipmentProvider类中做了实现 19. Android专门有个单元测试项目(Android Test Project),在这个项目中,可以新建一个继承AndroidTestCase类的具体测试类来单元测试某个功能.我新建了一个AndroidTestProject项目,在

Android学习笔记二十之Toast吐司、Notification通知、PopupWindow弹出窗

Android学习笔记二十之Toast吐司.Notification通知.PopupWindow弹出窗 Toast吐司 Toast吐司是我们经常用到的一个控件,Toast是AndroidOS用来显示消息的一种机制,它与Dialog不同,Toast不会获取到焦点,通常显示一段时间之后就会自动消失,下面我们来介绍Toast的几种常用方式: 第一种,默认显示方式,也是最常用的方式: Toast.makeText(MainActivity.this, "这是默认的显示方式", Toast.LE