Android Scroller简单用法,android底层开发教程

  1. /**

  2. * Called by a parent to request that a child update its values for mScrollX

  3. * and mScrollY if necessary. This will typically be done if the child is

  4. * animating a scroll using a {@link android.widget.Scroller Scroller}

  5. * object.

  6. */

  7. public void computeScroll()

  8. {

  9. }

computeScroll是一个空函数,很明显我们需要去实现它,至于做什么,就由我们自己来决定了。

因为View的子类很多,在下面的例子中,我会在一个自定义的类MyLinearLayout中去实现它。

ViewGroup.java

[java]  view plain copy

  1. @Override

  2. protected void dispatchDraw(Canvas canvas) {

  3. for (int i = 0; i < count; i++) {

  4. final View child = children[i];

  5. if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null)

  6. {

  7. more |= drawChild(canvas, child, drawingTime);

  8. }

从dispatchDraw函数可以看出,ViewGroup会对它的每个孩子调用drawChild(),  在下面的例子中, ContentLinearLayout的孩子有2个,是2个MyLinearLayout类型的实例。

再看看drawChild函数:

[java]  view plain copy

  1. protected boolean drawChild(Canvas canvas, View child, long drawingTime) {

  2. child.computeScroll();

  3. }

看到这里,我想大家应该就明白了,在父容器重画自己的孩子时,它会调用孩子的computScroll方法,也就是说例程中的ContentLinearLayout在调用dispatchDraw()函数时会调用MyLinearLayout的computeScroll方法。

这个computeScroll()函数正是我们大展身手的地方,在这个函数里我们可以去取得事先设置好的成员变量mScroller中的位置信息、速度信息等等,用这些参数来做我们想做的事情。

看到这里大家一定迫不及待的想看代码了,代码如下:

[java]  view plain copy

  1. package com.yulongfei.scroller;

  2. import android.widget.LinearLayout;

  3. import android.widget.Scroller;

  4. import android.app.Activity;

  5. import android.content.Context;

  6. import android.graphics.Canvas;

  7. import android.os.Bundle;

  8. import android.util.Log;

  9. import android.view.View;

  10. import android.widget.Button;

  11. import android.view.View.OnClickListener;

  12. public class TestScrollerActivity extends Activity {

  13. private static final String TAG = “TestScrollerActivity”;

  14. LinearLayout lay1,lay2,lay0;

  15. private Scroller mScroller;

  16. @Override

  17. public void onCreate(Bundle savedInstanceState) {

  18. super.onCreate(savedInstanceState);

  19. mScroller = new Scroller(this);

  20. lay1 = new MyLinearLayout(this);

  21. lay2 = new MyLinearLayout(this);

  22. lay1.setBackgroundColor(this.getResources().getColor(android.R.color.darker_gray));

  23. lay2.setBackgroundColor(this.getResources().getColor(android.R.color.white));

  24. lay0 = new ContentLinearLayout(this);

  25. lay0.setOrientation(LinearLayout.VERTICAL);

  26. LinearLayout.LayoutParams p0 = new LinearLayout.LayoutParams

  27. (LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);

  28. this.setContentView(lay0, p0);

  29. LinearLayout.LayoutParams p1 = new LinearLayout.LayoutParams

  30. (LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);

  31. p1.weight=1;

  32. lay0.addView(lay1,p1);

  33. LinearLayout.LayoutParams p2 = new LinearLayout.LayoutParams

  34. (LinearLayout.LayoutParams.FILL_PA

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

RENT,LinearLayout.LayoutParams.FILL_PARENT);

  1. p2.weight=1;

  2. lay0.addView(lay2,p2);

  3. MyButton btn1 = new MyButton(this);

  4. MyButton btn2 = new MyButton(this);

  5. btn1.setText(“btn in layout1”);

  6. btn2.setText(“btn in layout2”);

  7. btn1.setOnClickListener(new OnClickListener(){

  8. @Override

  9. public void onClick(View v) {

  10. mScroller.startScroll(0, 0, -30, -30, 50);

  11. }

  12. });

  13. btn2.setOnClickListener(new OnClickListener(){

  14. @Override

  15. public void onClick(View v) {

  16. mScroller.startScroll(20, 20, -50, -50, 50);

  17. }

  18. });

  19. lay1.addView(btn1);

  20. lay2.addView(btn2);

  21. }

  22. class MyButton extends Button

  23. {

  24. public MyButton(Context ctx)

  25. {

  26. super(ctx);

  27. }

  28. @Override

  29. protected void onDraw(Canvas canvas)

  30. {

  31. super.onDraw(canvas);

  32. Log.d(“MyButton”, this.toString() + " onDraw------");

  33. }

  34. }

  35. class MyLinearLayout extends LinearLayout

  36. {

  37. public MyLinearLayout(Context ctx)

  38. {

  39. super(ctx);

  40. }

  41. @Override

  42. /**

  43. * Called by a parent to request that a child update its values for mScrollX

  44. * and mScrollY if necessary. This will typically be done if the child is

  45. * animating a scroll using a {@link android.widget.Scroller Scroller}

  46. * object.

  47. */

  48. public void computeScroll()

  49. {

  50. Log.d(TAG, this.toString() + " computeScroll-----------");

  51. if (mScroller.computeScrollOffset())//如果mScroller没有调用startScroll,这里将会返回false。

  52. {

  53. //因为调用computeScroll函数的是MyLinearLayout实例,

  54. //所以调用scrollTo移动的将是该实例的孩子,也就是MyButton实例

  55. scrollTo(mScroller.getCurrX(), 0);

  56. Log.d(TAG, "getCurrX = " +  mScroller.getCurrX());

  57. //继续让系统重绘

  58. getChildAt(0).invalidate();

  59. }

  60. }

  61. }

  62. class ContentLinearLayout extends LinearLayout

  63. {

  64. public ContentLinearLayout(Context ctx)

  65. {

  66. super(ctx);

  67. }

  68. @Override

  69. protected void dispatchDraw(Canvas canvas)

  70. {

  71. Log.d(“ContentLinearLayout”, “contentview dispatchDraw”);

  72. super.dispatchDraw(canvas);

  73. }

  74. }

  75. }

对代码做一个简单介绍:

例子中定义了2个MyButton实例btn1和btn2,它们将被其父容器MyLinearLayout实例lay1和lay2通过调用scrollTo来移动。

ContentLinearLayout实例lay0为Activity的contentview,它有2个孩子,分别是lay1和lay2。

mScroller是一个封装位置和速度等信息的变量,startScroll()函数只是对它的一些成员变量做一些设置,这个设置的唯一效果就是导致mScroller.computeScrollOffset()    返回true。

这里大家可能有个疑问,既然startScroll()只是虚晃一枪,那scroll的动态效果到底是谁触发的呢?

后面我将给出答案。

运行程序,我们来看看Log

点击btn1:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值