有时候,我们在onCreate函数中调用ScrollBy函数、ScrollTo函数,会出现无效果的情况

public class ShowTraffic extends Activity

ScrollView mScrollView = null;

@Override
    protected void onCreate(Bundle savedInstanceState)
    {
       super.onCreate(savedInstanceState);

setContentView(R.layout.show);

mScrollView = (ScrollView) findViewById(R.id.show_scroll);

mScrollView.postDelayed(new Runnable()
         {
          @Override
           public void run()
           {
             int height = mLayout.getHeight();
             int sum  = mTraffics.mTraffics.size();
             mScrollView.scrollTo(0, (int) (height / sum * index ));
             Log.e("", "height:" + height + " sum:" + sum + " index:" + index);
           }}, 300);

}

}

按照我的理解,组件ScrollView和LinearLayout等,都是在onCreate的时候被创建,此时,组件的Height和Width等,都是未知的。所以,如果直接用getHeight()函数获取组件的高度,其返回值均为0。为了能够准确地获取组件的高度,我想到的办法是,采用postDelayed方法,延时执行获取高度或设置滚动值的代码。

布局是这样的

一个滚动布局中,包含了一个线性布局,而线性布局中又包含了若干线性布局,再往里面就是按钮、文本框之类的了。

mScrollView(ScrollView)

|______________ mLayout(LinearLayout)

|__________________itemLayout(LinearLayout)

|__________________itemLayout(LinearLayout)

|__________________itemLayout(LinearLayout)

|_.......

  • ScrollView 为一些没有滚动条的view 提供滚动条, 方法就是把需要滚动条的view 包含在 <ScrollView> 里面.

在Activity 的 onCreate() 方法(貌似在onStart和onResume也一样)中, 调用 mScrollView.scrollTo(0, 100); 是无效, 没有效果的. 找了半天, 终于在 http://stackoverflow.com/questions/3263259/scrollview-scrollto-not-working-saving-scrollview-position-on-rotation 找到答案. (Google 还是好过百度啊, 可惜快照不能用了)

scrollTo() 是直接指定滚动条的位置, 但是由于这个动作不是单纯关于 ScrollView 而已, 还要根据 ScrollView 里面包含的View 的实际信息. 所以这动作必须在页面加载完成以后才能执行.

在Activity 初始化过程中, 要指定滚动条位置, 必须用下面的代码

  1. mScrollView.post(new Runnable() {
  2. @Override
  3. public void run() {
  4. mScrollView.scrollTo(0, 1000);
  5. }
  6. });

post() 方法的说明:

Causes the Runnable to be added to the message queue. The runnable will be run on the user interface thread.

这段代码确确实实起到了作用, post() 方法是View 类就有的, 看来类似的问题不只 ScrollView 存在呢!

为了大概知道是什么原因, 我们从调试入手吧!

第一步, 先直接用 mScrollView.scrollTo(0, 1000); , 调试发现, activity 初始化过程中, scrollTo() 方法有被执行, 用F5, 内部执行了17 步.

第二步, 用post() 方法, 调试发现, activity 初始化过程中, post()执行, activity 初始化后, scrollTo() 方法才被执行, 用F5, 内部执行了25 步, 其中第18 步是 onScrollChanged(mScrollX, mScrollY, oldX, oldY);  但是效果的出现是在消息循环后.

第三步, 在onTouchEvent方法中, 执行调用mScrollView.scrollTo(0, 100); scrollTo() 方法有被执行, 用F5, 调试, 内部步骤很多, 绝对超过25了, 后面没耐心数了. 效果是在哪里出现也不清楚了.

我看了ScrollView 的源代码

  1. /**
  2. * {@inheritDoc}
  3. *
  4. * <p>This version also clamps the scrolling to the bounds of our child.
  5. */
  6. @Override
  7. public void scrollTo(int x, int y) {
  8. // we rely on the fact the View.scrollBy calls scrollTo.
  9. if (getChildCount() > 0) {
  10. View child = getChildAt(0);
  11. x = clamp(x, getWidth() - mPaddingRight - mPaddingLeft, child.getWidth());
  12. y = clamp(y, getHeight() - mPaddingBottom - mPaddingTop, child.getHeight());
  13. if (x != mScrollX || y != mScrollY) {
  14. super.scrollTo(x, y);
  15. }
  16. }
  17. }

它的父类View

  1. public void scrollTo(int x, int y) {
  2. if (mScrollX != x || mScrollY != y) {
  3. int oldX = mScrollX;
  4. int oldY = mScrollY;
  5. mScrollX = x;
  6. mScrollY = y;
  7. onScrollChanged(mScrollX, mScrollY, oldX, oldY);
  8. if (!awakenScrollBars()) {
  9. invalidate();
  10. }
  11. }
  12. }

看来是 if (mScrollX != x || mScrollY != y) 这个判断语句有没有通过是关键所在. 这也间接说明了, 在Activity 没初始化完成, ScrollView 对象获取的一些信息是不准确的, 直接导致了scrollTo() 方法无效.

Android中scrollview的scrollto方法不起作用的办法的更多相关文章

  1. android中的提示信息显示方法(toast应用)

    android中的提示信息显示方法(toast应用) (2011-10-17 11:02:06) 转载▼ 标签: android toast 杂谈 分类: Android android中toast的 ...

  2. 【转】Android中JNI的使用方法

    Android中JNI的使用方法 首先看一下Android平台的框架图:(网上盗用) 可以看到Android上层的Application和ApplicationFramework都是使用Java编写, ...

  3. android中ScrollView嵌套ListView或GridView显示位置问题

    Android中ScrollView中嵌套ListView或GridView时在开始进入界面时总是显示中间位置,开头的位置显示不出来.这种情况下只需要在ScrollView的父控件中添加以下两行代码即 ...

  4. Android多线程编程<一>Android中启动子线程的方法

          我们知道在Android中,要更新UI只能在UI主线程去更新,而不允许在子线程直接去操作UI,但是很多时候,很多耗时的工作都交给子线程去实现,当子线程执行完这些耗时的工作后,我们希望去修改 ...

  5. Android中JNI的使用方法(转载)

    Android中JNI的使用方法 首先看一下Android平台的框架图:(网上盗用) 可以看到Android上层的Application和ApplicationFramework都是使用Java编写, ...

  6. Android中锁定文件的方法

    androidSDK中并没有锁定文件相关的api. 但是android是基于linux操作系统的,linux比较底层,灵活性也更大,为了实现锁定文件的效果,大概有以下几种办法: 用chmod命令修改文 ...

  7. Android中的布局优化方法

    http://blog.csdn.net/rwecho/article/details/8951009 Android开发中的布局很重要吗?那是当然.一切的显示样式都是由这个布局决定的,你说能不重要吗 ...

  8. Android中Handler的使用方法及实例(基础回顾)

    Handler使用例1 这个例子是最简单的介绍handler使用的,是将handler绑定到它所建立的线程中.本次实验完成的功能是:单击Start按钮,程序会开始启动线程,并且线程程序完成后延时1s会 ...

  9. Android中 服务里的方法抽取成接口

    1 写个类继承Service 重写 onBind方法 返回一个IBinder 对象(传递到连接成功时用) 2 服务中 写一个内部类 继承IBinder 并且实现一个接口(用于抽取方法)继承IBinde ...

随机推荐

  1. Getopt::Long 模块的简单使用

    用法简介 1.带值参数传入程序内部 ※参数类型:整数, 浮点数, 字串 GetOptions( 'tag=s' => \$tag ); ‘=’表示此参数一定要有参数值, 若改用’:'代替表示参数 ...

  2. 未能解析目标框架“.NETFramework,Version=v4.0”的 mscorlib 错误的解决办法

    查看项目属性,发现该项目的目标框架是.NET Framework 4 Client Profile ,而被引用的程序集的目标框架是.NET Framework 4,将该项目的目标框架修改成.NET F ...

  3. python str + int

    TypeError: cannot concatenate 'str' and 'int' objects 1. print 'Is your secret number " + str(p ...

  4. Python 环境

    文章出处:http://www.cnblogs.com/winstic/,请保留此连接 总结一下自己使用python过程中安装三方包的方法 Python 安装 Python的安装非常简单,本人使用的w ...

  5. python中对文件、文件夹的操作需要涉及到os模块和shutil模块。

    创建文件:1) os.mknod("test.txt") 创建空文件2) open("test.txt",w) 直接打开一个文件,如果文件不存在则创建文件 创建 ...

  6. Javascript Framework Scenario

    Mobile----- zepto, jQuery Scroll------ iscrollhttp://cubiq.org/iscroll-4 jo.js widget----- jquery pl ...

  7. Perl ping

    <pre name="code" class="html">use Net::Ping; $p = Net::Ping->new(" ...

  8. hiho #1044 : 状态压缩·一

    描述 小Hi和小Ho在兑换到了喜欢的奖品之后,便继续起了他们的美国之行,思来想去,他们决定乘坐火车前往下一座城市——那座城市即将举行美食节! 但是不幸的是,小Hi和小Ho并没有能够买到很好的火车票—— ...

  9. 数据结构(KD树):HDU 4347 The Closest M Points

    The Closest M Points Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Ot ...

  10. 图论(A*算法,K短路) :POJ 2449 Remmarguts' Date

    Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 ...