【问题标题】:Android ScrollView, scroll before visibleAndroid ScrollView,在可见之前滚动
【发布时间】:2015-10-12 05:01:21
【问题描述】:

如何在滚动视图显示之前将其滚动设置为 x 像素?

在 ScrollView 我有一些视图,我知道它会填满屏幕。我可以滚动说第二个视图,以便在活动启动时第一个视图不可见吗?

现在我有这样的东西,但我认为它并不完美,有时我看到第一个视图,然后滚动到第二个

@Override
public void onGlobalLayout() {
    if (mHorizontalScrollView.getChildCount() > 0 && mHorizontalScrollView.getChildAt(0).getWidth() > mScreenWidth) {
            hsv.scrollTo(100, 0);
    }
}

编辑!!

第二次尝试是使用http://developer.android.com/reference/android/view/ViewTreeObserver.OnPreDrawListener.html 而不是http://developer.android.com/reference/android/view/ViewTreeObserver.OnGlobalLayoutListener.htmlOnPreDrawListener 我们可以读到At this point, all views in the tree have been measured and given a frame. Clients can use this to adjust their scroll bounds or even to request a new layout before drawing occurs. 所以基本上在这一点上我们应该调整滚动。所以我创建了:

@Override
public boolean onPreDraw() {
    if (hsv.getChildCount() > 0 && hsv.getChildAt(0).getWidth() > mScreenWidth) {
        hsv.scrollTo(100, 0);
        return false;
    }
    return true;
}

但现在它对我不起作用。

【问题讨论】:

  • 张贴代码以避免反对投票。
  • 我不知道为什么我会得到反对票,但是我已经准备添加一些代码,以表明我的想法。 ;)

标签: android


【解决方案1】:

我将onGlobalLayout 与下面的代码结合在一起。使用该 hack 并不是很好,但它仍然非常有效。当我收到 onGlobalLayout 事件时,我会检查布局是否完成,如果没问题,我会使用下面的方法。

// hsv - horizontal scroll view
private void forceShowColumn(final int column) {
    int scrollTo = childViewWidth * column;
    if (scrollTo == hsv.getScrollX()) {
        return;
    }
    hsv.scrollTo(scrollTo, 0);

    hsv.postDelayed(new Runnable() {

        @Override
        public void run() {
            forceShowColumn(column);
        }
    }, 10);
}

【讨论】:

    【解决方案2】:

    在 onCreate-method 中尝试 View.post(Runnable)。

    【讨论】:

    • 这是一个糟糕的解决方案 ;) 这是无法确定的,取决于运气。
    • 我很想知道您为什么判断 post() 不确定。另外,你最终还是使用了 postDelayed() ......
    【解决方案3】:

    我通过在控制我的 ScrollView 的片段中实现 View.OnLayoutChangeListener 解决了这个问题。

    public class YourFragment extends Fragment implements View.OnLayoutChangeListener{
    

    ...

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
    
        // Inflate the layout for this fragment
        view = inflater.inflate(R.layout.your_fragment_layout, container, false);
    
        //set scrollview layout change listener to be handled in this fragment
        sv = (ScrollView) view.findViewById(R.id.your_scroll_view);
        sv.addOnLayoutChangeListener(this);
    
        return view;
    }
    

    ...

    public void onLayoutChange (View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom){
        switch (v.getId())
        {
            case R.id.your_scroll_view:
            {
                    sv.scrollTo(0, sv.getTop());
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      正确的做法是在视图通过测量和布局后在 ScrollView 上调用 scrollTo(),否则 scrollView 中内容的宽度将为 0,因此 scrollTo() 将不滚动到正确的位置。通常在构造函数被调用并且视图被添加到它的父视图之后。

      请参阅http://developer.android.com/guide/topics/ui/how-android-draws.html,了解有关 android 如何绘制视图的更多信息。

      【讨论】:

      • 如您所见,我检查了是否设置了滚动视图子宽度。那么有没有另一种方法来检查我是否可以滚动?我也使用developer.android.com/reference/android/view/… 也许我应该使用developer.android.com/reference/android/view/…
      • 另一种可能性是在滚动视图中覆盖 onLayout() 并在 super.onLayout() 之后执行它
      • 是的,我曾经这样做过,但每次都无法正常工作,有时屏幕会闪烁。在 OnLayout 中,我什至检查了是否设置了尺寸。
      【解决方案5】:

      MrJre 给出了最优雅的解决方案:“在滚动视图中覆盖 onLayout() 并在 super.onLayout() 之后执行”

      此处的示例代码:

      https://stackoverflow.com/a/10209457/1310343

      【讨论】:

        【解决方案6】:

        使用:

        scrollTo (int x, int y)
        
        It sets the scrolled position of your view. This will cause a call to onScrollChanged
        

        更多详情:见此

        ScrollView ScrollTo

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-05-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多