监听横向滚动事件的HorizontalScrollView Android

15

我试图监听HorizontalScrollView滚动时的事件。我尝试过以下代码,但它什么也没打印出来。

HorizontalScrollView headerScrollView = new HorizontalScrollView(this);

    headerScrollView.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            Log.i("hv1",event.toString());
            Log.i("hv1","HELLO");
            return false;
        }
    });
实际问题是,我想同时滚动两个HorizontalScrollView,也就是说,当它们中至少有一个被滚动时,它们需要同时滚动。有什么解决方法吗?
我使用了下面的答案,但不确定我需要如何使用类中的方法。
TestHorizontalScrollView headerScrollView = (TestHorizontalScrollView) findViewById(R.id.headerHv); 

我需要在布局文件中指向hsv元素,这样做是正确的吗?

6个回答

28
您可以尝试创建一个自定义类,继承HorizontalScrollView,并覆盖onScrollChanged()函数,如下所示。
public class TestHorizontalScrollView extends HorizontalScrollView {

    public TestHorizontalScrollView(Context context) {
        super(context);
    }


    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        // TODO Auto-generated method stub
        Log.i("Scrolling", "X from ["+oldl+"] to ["+l+"]");
        super.onScrollChanged(l, t, oldl, oldt);
    }

}

这个被重写的函数将会捕捉到所有滚动位置的变化,即使视图没有被触摸。这可以保持你的滚动视图同步。


这是否类似于Android上的默认新闻和天气应用程序?您可以在ListView之间左右滚动,除了有两个ListView外?我想知道是否可以将两个ListView合并为一个,并使用LinearLayouts分离两侧。试图将其可视化 :) - David
嗯...我觉得你没理解对..让我用更好的例子再解释一遍。我需要设计一个类似于Excel电子表格的表格,列标题存储在一个列表中,下面的内容存储在另一个列表中(这将有几行)...当下面的列表(内容)滚动时,标题也应该随之滚动。我需要有两个单独的列表(标题和内容),因为这种表格将是通用表格,并且将在运行时使用不同的标题和内容构建... - i_raqz
我相信我之前已经完成了上面提供的内容。我晚上稍后会检查一下。一旦我验证了解决方案,我可以编辑我的帖子。 :) - David
我该如何在我的ArrayAdapter类中使用它? - Manikanta Ottiprolu
@Manikanta 这是一个非常古老的帖子。你可能想要提出一个新问题并引用这个帖子。此外,你可能想要说明你试图实现什么目标。如果你询问你想要实现的目标(假设是水平列表视图或其他类似控件),可能会有一些库或开源代码可供使用,可以得到更好的帮助。 - David
显示剩余3条评论

8

这是一个老问题,但或许仍有帮助。您可以按照以下方式操作:

scrollOne = (HorizontalScrollView)findViewById(R.id.horizontal_one);
scrollTwo = (HorizontalScrollView)findViewById(R.id.horizontal_two);

scrollTwo.setOnTouchListener(new OnTouchListener(){

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        // TODO Auto-generated method stub

        int scrollX = view.getScrollX();
        int scrollY = view.getScrollY();

        scrollOne.scrollTo(scrollX, scrollY);
                    return false;
        }

    });

1
嘿,谢谢你的回答。但是当我再次将HorizontalScrollView移回原始位置时,第一个不会随着它一起移动...我错过了什么? - Looking Forward
我认为问题在于您没有将两个滚动视图都设置为监听器。使用上面的示例来处理两个水平滚动视图,此示例中的scrollOne还需要一个onTouchListener,在其中移动scrollTwo。 - Opiatefuchs
我没有理解你的回答。 我已经在这里更新了我的代码... 你能告诉我我错过了什么吗? - Looking Forward
而且,当然我忘了的是,如果您以编程方式滚动任何scrollView,则必须在其中滚动时执行此代码。上面的示例仅适用于onTouch。 - Opiatefuchs
hs2.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub int scrollX = v.getScrollX(); int curX = scrollX; hs1.scrollBy(scrollX, 0); return false; } }); - Looking Forward
显示剩余2条评论

5

具有监听器的ScrollView,API < 23

在您的代码中编写以下内容

MyHorizontalScrollView scrollView = (MyHorizontalScrollView)view.findViewById(R.id.scrollViewBrowse);
        scrollView.setOnScrollChangedListener(new MyHorizontalScrollView.OnScrollChangedListener() {
            @Override
            public void onScrollChanged(int l, int t, int oldl, int oldt) {

            }
        });

MyHorizontalScrollView

   public class MyHorizontalScrollView extends ScrollView {

        public OnScrollChangedListener mOnScrollChangedListener;

        public MyHorizontalScrollView(Context context) {
            super(context);
        }

        public MyHorizontalScrollView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        public MyHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }

        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            super.onScrollChanged(l, t, oldl, oldt);

            if (mOnScrollChangedListener != null) {
                mOnScrollChangedListener.onScrollChanged(l, t, oldl, oldt);
            }
        }

        public void setOnScrollChangedListener(OnScrollChangedListener onScrollChangedListener){
            this.mOnScrollChangedListener = onScrollChangedListener;
        }

        public interface OnScrollChangedListener{
            void onScrollChanged(int l, int t, int oldl, int oldt);
        }

    }

* Xml文件 *

<MyHorizontalScrollView
        android:id="@+id/scrollViewBrowse"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/backgroung"
        android:padding="10dp">
 </MyHorizontalScrollView>

2
为了避免 API 级别的问题,请按照以下步骤操作。
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
            int scrollY = scrollView.getScrollY(); 
            int scrollX = scrollView.getScrollX();

            if (scrollY > 500) {

            } else {

            }
        }
    });

0

你可以试试这个,我尝试了很多方法,但都不符合我的需求,然后我尝试自己做,成功了,而且看起来很好,非常顺畅。

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <com.szl.fundlistdemo.WrapContentListView
            android:id="@+id/left_lv"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:scrollbars="none"/>

        <HorizontalScrollView
            android:id="@+id/hscrollview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <com.szl.fundlistdemo.WrapContentListView
                android:id="@+id/right_lv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

        </HorizontalScrollView>
    </LinearLayout>


</ScrollView>

public class WrapContentListView extends ListView{
public WrapContentListView(Context context) {
    super(context);
}

public WrapContentListView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public WrapContentListView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, expandSpec);
}
}

0

基于 @Dipak 在 kotlin 中的回答:

binding.scrollList.viewTreeObserver.addOnScrollChangedListener {
     val X = binding.scrollList.scrollX
     val Y = binding.scrollList.scrollY
}

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