android - 以编程方式使 Scrollview 不可滚动并将其改回
问题描述
我试图在滚动视图到达 scrollY 位置时停止滚动。然后,当子视图(recyclerview)到达顶部或过度滚动时,将其更改回可滚动。
我尝试了两种方法
- onTouchListener - 它不与 scrollY 位置交互
nestedScrollView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return false;
}
});
- setOnScrollChangeListener - 不知道如何将其设置为不可滚动
nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (scrollY >400dp) {
}
}
编辑 1 个 XML
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<Linearlayout
android:layout_width="match_parent"
android:layout_height="match_parent">
//include more contents card
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="true"
android:orientation="vertical"
/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
解决方案
您的想法OnTouchListener
是可行的,但 Android 期望的返回值令人困惑。false
表示滚动已激活。true
表示滚动已停用。
这将防止滚动:
scrollView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
来自View.java
:
/**
* Called when a touch event is dispatched to a view. This allows listeners to
* get a chance to respond before the target view.
*
* @param v The view the touch event has been dispatched to.
* @param event The MotionEvent object containing full information about
* the event.
* @return True if the listener has consumed the event, false otherwise.
*/
boolean onTouch(View v, MotionEvent event);
编辑:
您可以同时使用您的两个侦听器并通过实例变量“连接”它们。像这样:
boolean freezeScrolling = false; //This has to be an instance variable so both Listeners can access it.
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
ScrollView scrollView = findViewById(R.id.scroll_view);
Button button = findViewById(R.id.button);
scrollView.setOnScrollChangeListener(new ScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
// Log.d("TAG", String.valueOf(scrollY));
freezeScrolling = (scrollY>100); //freeScrolling is set to true if scrollY is above 100. Otherwise to false.
}
});
scrollView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return freezeScrolling; //onTouch returns the value which has been set in onScrollChange.
}
});
//unfreezing test:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scrollView.scrollTo(0, 0); //freezeScrolling will be changed automatically.
}
});
推荐阅读
- java - 求地图到地图转换的优化建议
- reactjs - 在地图中间过滤>0时如何避免显示错误
- c# - 为什么结合 Task.Run 和 plinq 这么慢?
- postman - 基于来自 arrayElement 的响应的 JSON 验证检查
- c# - 为什么单元测试 Assert.AreEqual() 方法不会在自定义类中选择我自己的 Equals() 方法
- jquery - Jquery UI Autocomplete Custom HTML (TypeError: t.item is undefined)
- react-native - 如何避免日期字符串之间的换行?[反应原生]
- android - Android Api (Okhttps) 未在 android 9(pie) 及更高版本中调用
- c# - 如何简化从excel到sqlite的查询?
- docker - docker-compose.yaml 什么时候重新解析?