自动滚动到HorizontalScrollView

8

我正在进行自动水平滚动。所以我有15个项目。现在我想访问第12个项目,因此我的索引是11。但是当索引出现时,我无法自动滚动它。

 horizontalScrollView.scrollTo(12, 0);

@Override
public void onPageSelected(int page) {
    for(int i = 0; i < holeTitle.length; i++) {
        if(i == page) {
            title[i].setTextColor(0xffffffff);
horizontalScrollView.scrollTo(12, 0);

        }
        else {
            title[i].setTextColor(0xffe0e0e0);

        }
    }

}

请专家查看一下。


请问您尝试这个时,具体出了什么问题? - Dawood ibn Kareem
我的第12个项目应该是可见的自动滚动。目前它是隐藏的,我必须手动滚动它。 - Rahul Rawat
4个回答

16

DmRomantsov的回答是滚动到第12个按钮的正确方法。然而,getLeft()getRight()方法返回0,因为布局尚未显示在屏幕上。现在计算布局父级和子项的宽度还为时过早。要实现它,你需要在onWindowFocusChanged内部执行自动滚动。

@Override
public void onWindowFocusChanged(boolean hasFocus){
    super.onWindowFocusChanged(hasFocus);
    if(hasFocus){
        // do smoothScrollTo(...);
    }
} 

然而,在 Fragment 中,上面的方法将不起作用。我只是写了这个来给一个提示,让大家理解这个概念。为了在 Fragment 中具有相同的行为,你只需要使用一个 Runnable 来给你的 UI 显示时间。然后,使用一个水平定向的 LinearLayout

// Init variables
HorizontalScrollView mHS;
LinearLayout mLL;  

// onCreateView method
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.layout_container, container, false);

    // Find your views
    mHS = (HorizontalScrollView)view.findViewById(R.id.hscrollview);
    mLL = (LinearLayout)view.findViewById(R.id.hscrollview_container);  

    // Do a Runnable on the inflated view
    view.post(new Runnable() {
        @Override
        public void run() {
            Log.v("","Left position of 12th child = "+mLL.getChildAt(11).getLeft());
            mHS.smoothScrollTo(mLL.getChildAt(11).getLeft(), 0);
        }
    });
    return view;
}

中间的 HorizontalScrollView:

你的问题是要自动滚动到第 12 个子元素。然而,在下面的评论中,你要求我在 HorizontalScrollView 的中间自动滚动,我假设在每台设备上都需要这样做。你需要计算屏幕的宽度、容器的总宽度以及在设备宽度内显示了多少个子元素。以下是一个简单的代码:

// Auto scroll to the middle (regardless of the width screen)
view.post(new Runnable() {
    @Override
    public void run() {
        // Width of the screen
        DisplayMetrics metrics = getActivity().getResources()
                                 .getDisplayMetrics();
        int widthScreen = metrics.widthPixels;
        Log.v("","Width screen total = " + widthScreen);

        // Width of the container (LinearLayout)
        int widthContainer = mLL.getWidth();
        Log.v("","Width container total = " + widthContainer );

        // Width of one child (Button)
        int widthChild = mLL.getChildAt(0).getWidth();
        Log.v("","Width child = " + widthChild);

        // Nb children in screen    
        int nbChildInScreen = widthScreen / widthChild;
        Log.v("","Width screen total / Width child = " + nbChildInScreen);

        // Width total of the space outside the screen / 2 (= left position)
        int positionLeftWidth = (widthContainer 
                                - (widthChild * nbChildInScreen))/2;
        Log.v("","Position left to the middle = " + positionLeftWidth);

        // Auto scroll to the middle
        mHS.smoothScrollTo(positionLeftWidth, 0);

    }
});

/** 
  * Your value might be resumed by:
  *
  * int positionLeftWidth = 
  *       ( mLL.getWidth() - ( mLL.getChildAt(0).getWidth() * 
  *       ( metrics.widthPixels / mLL.getChildAt(0).getWidth() ) ) ) / 2;  
  *
**/

带有选定值的中间HorizontalScrollView:

我有一些误解真正的需求。实际上,您想要自动滚动到选定的子视图,并将该视图显示在屏幕中间。
然后,我修改了最后一个int positionLeftWidth,它现在指的是所选视图相对于其父视图的左侧位置一个屏幕中包含的子项数所选视图的一半宽度。因此,除了positionLeftWidth之外,代码与上面相同:

// For example the chosen value is 7

// 7th Child position left    
int positionChildAt = mLL.getChildAt(6).getLeft();

// Width total of the auto-scroll (positionLeftWidth)
int positionLeftWidth = positionChildAt - // position 7th child from left less
                ( ( nbChildInScreen    // ( how many child contained in screen
                  * widthChild ) / 2 ) // multiplied by their width ) divide by 2
                + ( widthChild / 2 );  // plus ( the child view divide by 2 )

// Auto-scroll to the 7th child
mHS.smoothScrollTo(positionLeftWidth, 0);  

无论在getChildAt()方法中传入什么值,以及屏幕的宽度是多少,你总能将所选择的(在你的情况下)按钮置于屏幕中央。


它对我有效。它是滚动视图的左侧。但我正在尝试在中心显示。 - Rahul Rawat
是的,我想在HorizontalScrollView的中间自动滚动。 - Rahul Rawat
@Filo 我无法看到居中显示。仍然显示在左侧。 - Rahul Rawat
@RahulRawat 已经测试过了,我刚刚在NexusOne(2.2)和Nexus4(4.4)上测试了上面的代码 - 各测试了两次 - 完美运行。如果可能的话,您能通过编辑您的问题来展示您的操作吗? - Blo
1
世界上最好的解决方案! - Ghasem Sadeghi
显示剩余4条评论

4

尝试

horizontalScrollView.smoothScrollTo(horizontalScrollView.getChildAt(11).getRight(),0);

第一个参数 - X轴坐标,第二个参数 - Y轴坐标。
偏移量:

public final void smoothScrollBy (int dx, int dy)

绝对值:
public final void smoothScrollTo (int x, int y)

出现了空指针异常。我的子项是一个LinearLayout,这个布局包含了15个项目。 - Rahul Rawat
是的,这很有用,但是我始终得到getLeft()的0。我正在使用Fragment。 - Rahul Rawat

2
尝试使用`horizontalScrollView.smoothScrollBy(12, 0);`进行水平滚动。

0

尝试这个可行的代码。位置将是您想要滚动的位置

  final HorizontalScrollView mHorizontalScrollView = (HorizontalScrollView) .findViewById(R.id.horizontalScrollView);
        mHorizontalScrollView.postDelayed(new Runnable() {
            @Override
            public void run() {
                mHorizontalScrollView.scrollTo(position, 0);
                mHorizontalScrollView.smoothScrollBy(1200, 0);
            }
        },100);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接