如何在 android RecyclerView 中检测 OverScroll?
How do I detect OverScroll in android RecyclerView?
我试图覆盖 onOverScrolled() 但它没有被触发:
public class MyRecyclerView extends RecyclerView {
public MyRecyclerView(@NonNull Context context) {
super(context);
}
public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
Toast.makeText(getContext(), "overScrolled", Toast.LENGTH_SHORT).show();
}
}
我的 RecyclerView 有 recyclerView.setOverScrollMode(View.OVER_SCROLL_ALWAYS);
试试这个来查找 bottom overscroll
和 top overscroll
Find bottom overscroll
and top overscroll
Using LayoutManager
import android.os.Bundle;
import java.util.ArrayList;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class MainActivity extends AppCompatActivity {
RecyclerView myRecyclerView;
ArrayList<String> arrayList = new ArrayList<>();
DataAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myRecyclerView = findViewById(R.id.myRecyclerView);
LinearLayoutManager linearLayoutManager= new LinearLayoutManager(this){
@Override
public int scrollVerticallyBy ( int dx, RecyclerView.Recycler recycler, RecyclerView.State state ) {
int scrollRange = super.scrollVerticallyBy(dx, recycler, state);
int overScroll = dx - scrollRange;
if (overScroll > 0) {
Utils.printLog("NILU_PILU :-> BOTTOM OVERSCROLL");
} else if (overScroll < 0) {
Utils.printLog("NILU_PILU :-> TOP OVERSCROLL");
}
return scrollRange;
}
};
myRecyclerView.setLayoutManager(linearLayoutManager);
myRecyclerView.setHasFixedSize(true);
addDataToList();
adapter = new DataAdapter(this, arrayList);
myRecyclerView.setAdapter(adapter);
}
private void addDataToList() {
for (int i = 0; i < 50; i++) {
arrayList.add("NILU_PILU :-> " + i);
}
}
}
Find bottom overscroll
Using RecyclerView.addOnScrollListener()
myRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
int pos = linearLayoutManager.findLastVisibleItemPosition();
int numItems = myRecyclerView.getAdapter().getItemCount();
if (pos >= numItems - 1 ) {
Utils.printLog("NILU_PILU :-> BOTTOM OVERSCROLL");
}
}
}
});
这是我在 reddit 上找到的解决方案:
创建一个自定义的 LinearLayoutManager 而不是自定义的 recyclerview,只需覆盖布局管理器 scrollVerticallyBy()
方法并检查 dx/dy 减去超级实现返回的值是否为 != 0。然后发生了过度滚动。
@Override
public int scrollVerticallyBy ( int dx, RecyclerView.Recycler recycler,
RecyclerView.State state ) {
int scrollRange = super.scrollVerticallyBy(dx, recycler, state);
int overscroll = dx - scrollRange;
if (overscroll > 0) {
// bottom overscroll
} else if (overscroll < 0) {
// top overscroll
}
return scrollRange;
}
我试图覆盖 onOverScrolled() 但它没有被触发:
public class MyRecyclerView extends RecyclerView {
public MyRecyclerView(@NonNull Context context) {
super(context);
}
public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
Toast.makeText(getContext(), "overScrolled", Toast.LENGTH_SHORT).show();
}
}
我的 RecyclerView 有 recyclerView.setOverScrollMode(View.OVER_SCROLL_ALWAYS);
试试这个来查找 bottom overscroll
和 top overscroll
Find
bottom overscroll
andtop overscroll
Using LayoutManager
import android.os.Bundle;
import java.util.ArrayList;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class MainActivity extends AppCompatActivity {
RecyclerView myRecyclerView;
ArrayList<String> arrayList = new ArrayList<>();
DataAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myRecyclerView = findViewById(R.id.myRecyclerView);
LinearLayoutManager linearLayoutManager= new LinearLayoutManager(this){
@Override
public int scrollVerticallyBy ( int dx, RecyclerView.Recycler recycler, RecyclerView.State state ) {
int scrollRange = super.scrollVerticallyBy(dx, recycler, state);
int overScroll = dx - scrollRange;
if (overScroll > 0) {
Utils.printLog("NILU_PILU :-> BOTTOM OVERSCROLL");
} else if (overScroll < 0) {
Utils.printLog("NILU_PILU :-> TOP OVERSCROLL");
}
return scrollRange;
}
};
myRecyclerView.setLayoutManager(linearLayoutManager);
myRecyclerView.setHasFixedSize(true);
addDataToList();
adapter = new DataAdapter(this, arrayList);
myRecyclerView.setAdapter(adapter);
}
private void addDataToList() {
for (int i = 0; i < 50; i++) {
arrayList.add("NILU_PILU :-> " + i);
}
}
}
Find
bottom overscroll
UsingRecyclerView.addOnScrollListener()
myRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
int pos = linearLayoutManager.findLastVisibleItemPosition();
int numItems = myRecyclerView.getAdapter().getItemCount();
if (pos >= numItems - 1 ) {
Utils.printLog("NILU_PILU :-> BOTTOM OVERSCROLL");
}
}
}
});
这是我在 reddit 上找到的解决方案:
创建一个自定义的 LinearLayoutManager 而不是自定义的 recyclerview,只需覆盖布局管理器 scrollVerticallyBy()
方法并检查 dx/dy 减去超级实现返回的值是否为 != 0。然后发生了过度滚动。
@Override
public int scrollVerticallyBy ( int dx, RecyclerView.Recycler recycler,
RecyclerView.State state ) {
int scrollRange = super.scrollVerticallyBy(dx, recycler, state);
int overscroll = dx - scrollRange;
if (overscroll > 0) {
// bottom overscroll
} else if (overscroll < 0) {
// top overscroll
}
return scrollRange;
}