有时候,我们在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. javascript——操作符(~、&、|、^、<<、>>)

    直接上代码吧! <script type="text/javascript"> //javascript操作符 //1.按位非~ var num1=25;// var ...

  2. 自定义复选框 checkbox 样式

    默认的复选框样式一般在项目中都很少用 ,看起来也丑丑的.这里提供一个优化样式后的复选框.原理就是隐藏掉默认样式,在用设计好的样式替代 html结构 <div> <input type ...

  3. TatukGIS-TGIS_Editor.CreateShape

    procedure CreateShape(const _layer: TObject; const _ptg: TGIS_Point3D; const _type: TGIS_ShapeType; ...

  4. Python 异常处理--raise函数用法

    raise语句手工引发一个异常: "raise" [expression ["," expression ["," expression]] ...

  5. js的引用顺序

    注意:Bootstrap中的JS插件依赖于JQuery,因此JQuery要在Bootstrap之前引用!!! 把JS文件引用放入body的最下面,是为了使js在网页全部加载完后才起作用,比如你的js里 ...

  6. MSSQL中datetime与unix时间戳互转

    //ms sql datetime 转unix时间戳 SELECT DATEDIFF(s, '19700101',GETDATE()) //ms sql unix时间戳 转datetime 涉及到时区 ...

  7. bzoj3637: Query on a tree VI

    Description You are given a tree (an acyclic undirected connected graph) with n nodes. The tree node ...

  8. phalapi

    public为程序入口 Demo和MyApp为具体的实现 public为多入口 demo和myapp都是入口,但是进入后即又为单入口 list为接口文档,是自动解析程序里的注释自动生成的文档 框架执行 ...

  9. swfobject.js IE兼容问题

    错误代码 在562行左右 / add style rule if (ua.ie && ua.win) { if (dynamicStylesheet && typeof ...

  10. BZOJ 1031 字符加密

    Description 喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作 ...