如何检测Android滚动视图是否处于空闲状态?
How to detect whether Android Scroll view is in idle state?
我试图在滚动视图处于空闲状态时隐藏按钮 state.the 按钮应该仅在滚动期间不可见。(其余时间按钮应该可见)
scrollView.setOnScrollChangeListener(new ScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (scrollX == scrollY) {
Button.setVisibility(View.VISIBLE);
} else if ((scrollY > oldScrollY)) {
Button.setVisibility(View.INVISIBLE);
}
}
});
试试下面的代码
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState == SCROLL_STATE_IDLE){
//do your stuff here
}
}
找到解决方案
scrollView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch( View v, MotionEvent event ) {
switch ( event.getAction( ) ) {
case MotionEvent.ACTION_SCROLL:
case MotionEvent.ACTION_MOVE:
Log.e( "SCROLL", "ACTION_SCROLL" );
break;
case MotionEvent.ACTION_DOWN:
Log.e( "SCROLL", "ACTION_DOWN" );
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
Log.e( "SCROLL", "SCROLL_STOP" );
break;
}
return false;
}
});
尽管这个问题有点老,而且 ScrollView
没有像以前那样使用,但我不得不实现与此相关的东西,我根据建议和 Kotlin 使用了 NestedScrollView
。
如果您使用的是 Java,这将不可能或作为 'clean',您将需要创建静态 util 方法,使用 Kotlin,您可以执行扩展功能,如图所示。
如果您使用的是 ScrollView
,只需将您在此处看到的内容从 NestedScrollView
更改为 ScrollView
。
我将展示两种实现方法:
首先,创建您的 NestedScrollViewExtensions.kt
文件:
1.
如果您想要一个简化的(我喜欢的)版本,只需将此片段添加到您的 NestedScrollViewExtensions.kt
文件中:
fun NestedScrollView.onScrollStateChanged(startDelay: Long = 100, stopDelay: Long = 400, listener: (Boolean) -> Unit) {
setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_SCROLL, MotionEvent.ACTION_MOVE -> {
handler.postDelayed({
listener.invoke(true)
}, startDelay)
}
MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
handler.postDelayed({
listener.invoke(false)
}, stopDelay)
}
}
false // Do not consume events
}
}
这样实现更简洁:
scroll_view.onScrollStateChanged { isScrolling ->
if(isScrolling) fab.shrink() else fab.extend()
}
2
而且不太干净的方式
interface NestedViewScrollChangedListener {
fun onScrollStart()
fun onScrollStop()
}
@SuppressLint("ClickableViewAccessibility")
fun NestedScrollView.onScrollStateChanged(listener: NestedViewScrollChangedListener) {
this.setOnTouchListener { _, event ->
when(event.action) {
MotionEvent.ACTION_SCROLL, MotionEvent.ACTION_MOVE -> {
handler.postDelayed({
listener.onScrollStart()
}, 100)
}
MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
handler.postDelayed({
listener.onScrollStop()
}, 400)
}
}
false // Don't consume touch events
}
}
在这里我使用了一个适合我的简单延迟,因为我需要让动画发生,随意删除所有 handler.postDelay()
并直接调用侦听器。
NestedViewScrollChangedListener
上面的接口需要这样实现:
scroll_view.onScrollStateChanged(object : NestedViewScrollChangedListener {
override fun onScrollStart() {
fab.shrink()
}
override fun onScrollStop() {
fab.extend()
}
})
祝你好运:)
在科特林中你可以使用这个
inline fun NestedScrollView.scrollState(crossinline idle: () -> Unit, crossinline scrolled: () -> Unit) {
setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_SCROLL,
MotionEvent.ACTION_MOVE,
MotionEvent.ACTION_DOWN -> {
scrolled()
}
MotionEvent.ACTION_CANCEL,
MotionEvent.ACTION_UP -> {
idle()
}
}
false
}
}
我试图在滚动视图处于空闲状态时隐藏按钮 state.the 按钮应该仅在滚动期间不可见。(其余时间按钮应该可见)
scrollView.setOnScrollChangeListener(new ScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (scrollX == scrollY) {
Button.setVisibility(View.VISIBLE);
} else if ((scrollY > oldScrollY)) {
Button.setVisibility(View.INVISIBLE);
}
}
});
试试下面的代码
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState == SCROLL_STATE_IDLE){
//do your stuff here
}
}
找到解决方案
scrollView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch( View v, MotionEvent event ) {
switch ( event.getAction( ) ) {
case MotionEvent.ACTION_SCROLL:
case MotionEvent.ACTION_MOVE:
Log.e( "SCROLL", "ACTION_SCROLL" );
break;
case MotionEvent.ACTION_DOWN:
Log.e( "SCROLL", "ACTION_DOWN" );
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
Log.e( "SCROLL", "SCROLL_STOP" );
break;
}
return false;
}
});
尽管这个问题有点老,而且 ScrollView
没有像以前那样使用,但我不得不实现与此相关的东西,我根据建议和 Kotlin 使用了 NestedScrollView
。
如果您使用的是 Java,这将不可能或作为 'clean',您将需要创建静态 util 方法,使用 Kotlin,您可以执行扩展功能,如图所示。
如果您使用的是 ScrollView
,只需将您在此处看到的内容从 NestedScrollView
更改为 ScrollView
。
我将展示两种实现方法:
首先,创建您的 NestedScrollViewExtensions.kt
文件:
1.
如果您想要一个简化的(我喜欢的)版本,只需将此片段添加到您的 NestedScrollViewExtensions.kt
文件中:
fun NestedScrollView.onScrollStateChanged(startDelay: Long = 100, stopDelay: Long = 400, listener: (Boolean) -> Unit) {
setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_SCROLL, MotionEvent.ACTION_MOVE -> {
handler.postDelayed({
listener.invoke(true)
}, startDelay)
}
MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
handler.postDelayed({
listener.invoke(false)
}, stopDelay)
}
}
false // Do not consume events
}
}
这样实现更简洁:
scroll_view.onScrollStateChanged { isScrolling ->
if(isScrolling) fab.shrink() else fab.extend()
}
2
而且不太干净的方式
interface NestedViewScrollChangedListener {
fun onScrollStart()
fun onScrollStop()
}
@SuppressLint("ClickableViewAccessibility")
fun NestedScrollView.onScrollStateChanged(listener: NestedViewScrollChangedListener) {
this.setOnTouchListener { _, event ->
when(event.action) {
MotionEvent.ACTION_SCROLL, MotionEvent.ACTION_MOVE -> {
handler.postDelayed({
listener.onScrollStart()
}, 100)
}
MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
handler.postDelayed({
listener.onScrollStop()
}, 400)
}
}
false // Don't consume touch events
}
}
在这里我使用了一个适合我的简单延迟,因为我需要让动画发生,随意删除所有 handler.postDelay()
并直接调用侦听器。
NestedViewScrollChangedListener
上面的接口需要这样实现:
scroll_view.onScrollStateChanged(object : NestedViewScrollChangedListener {
override fun onScrollStart() {
fab.shrink()
}
override fun onScrollStop() {
fab.extend()
}
})
祝你好运:)
在科特林中你可以使用这个
inline fun NestedScrollView.scrollState(crossinline idle: () -> Unit, crossinline scrolled: () -> Unit) {
setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_SCROLL,
MotionEvent.ACTION_MOVE,
MotionEvent.ACTION_DOWN -> {
scrolled()
}
MotionEvent.ACTION_CANCEL,
MotionEvent.ACTION_UP -> {
idle()
}
}
false
}
}