- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
尝试了所有相关问题,但没有成功:(
我正在使用 Recycler View 构建无限滚动。
问题:始终会在用户不滚动屏幕的情况下调用 onScrolled 方法。
Android 文档指南对此 onScrolled 方法进行了描述:
Case 1) Callback method to be invoked when the RecyclerView has been scrolled. This will be called after the scroll has completed.
Case 2) This callback will also be called if visible item range changes after a layout calculation. In that case, dx and dy will be 0.
由于情况 2,我的 onScrolled 方法在用户没有滚动的情况下被调用。我在屏幕中记录了 dy,结果发现 onScrolled 是通过 dy=0 调用的。这发生在第二种情况。
如果我使用:
if (dy > 0){
// The user is scrolling down
}
事实证明,无论我滚动 Recycler View 多少次,我的 onScrolled 方法都不会被调用。
RecyclerAdapterSmallVideos.java
public class RecyclerAdapterSmallVideos extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<VideosBigSize> videosBigSizeList;
private Context mContext;
final int VIEW_TYPE_ITEM = 0, VIEW_TYPE_LOADING = 1;
ILoadMore loadMore;
boolean isLoading;
int visibleThreshold = 5;
int lastVisibleItem, totalItemCount;
public RecyclerAdapterSmallVideos(RecyclerView recyclerView, Context context, List<VideosBigSize> videosBigSizeList) {
this.videosBigSizeList = videosBigSizeList;
this.mContext = context;
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if (!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
if (loadMore != null) {
// This is running without the user scrolling the Recycler View.
loadMore.onLoadMore();
}
isLoading = true;
}
}
});
}
@Override
public int getItemViewType(int position) {
return videosBigSizeList.get(position) == null ? VIEW_TYPE_LOADING: VIEW_TYPE_ITEM;
}
public void setLoadMore(ILoadMore loadMore) {
this.loadMore = loadMore;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_ITEM) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_small_video, parent, false);
return new ViewHolderSmallVideos(view);
} else if (viewType == VIEW_TYPE_LOADING) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_loading, parent, false);
return new ViewHolderLoading(view);
}
return null;
}
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
/*########### Case 1) The holder is a instance off ViewHolderSmallVideos (Items) ###########*/
if (holder instanceof ViewHolderSmallVideos) {
Log.i("Debugging", "onBindViewHolder: Binding instance of ViewHolder SmallVideos: " + holder.getAdapterPosition());
VideosBigSize singleVideoBigSize = videosBigSizeList.get(position);
ViewHolderSmallVideos viewHolderSmallVideos = (ViewHolderSmallVideos) holder;
// Step 1) Images
GlideApp.with(viewHolderSmallVideos.thumbNail.getContext())
.load(singleVideoBigSize.getThumnail_url())
.centerCrop()
.into(viewHolderSmallVideos.thumbNail); // Video Thumbnail
// Step 2) Determine the Max Length for each TextView
setTextMaxLength(viewHolderSmallVideos.videoTitle, viewHolderSmallVideos.channelName, mContext);
// Step 3) Texts
viewHolderSmallVideos.videoTitle.setText(singleVideoBigSize.getVideo_title());
viewHolderSmallVideos.channelName.setText(singleVideoBigSize.getChannel_name());
viewHolderSmallVideos.videoViews.setText(singleVideoBigSize.getVideo_views());
viewHolderSmallVideos.videoUploadDate.setText(singleVideoBigSize.getVideo_upload_date());
viewHolderSmallVideos.videoDuration.setText(singleVideoBigSize.getVideo_duration());
// Step 4) Handle clicks
viewHolderSmallVideos.constraintLayoutEachItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext, String.valueOf(holder.getAdapterPosition()), Toast.LENGTH_SHORT).show();
}
});
}
/*########### Case 2) The holder is a instance off ViewHolderLoading (progressBar) ###########*/
else if (holder instanceof ViewHolderLoading) {
Log.i("Debugging", "onBindViewHolder: Binding instance of ViewHolder Loading: " + holder.getAdapterPosition());
ViewHolderLoading viewHolderLoading = (ViewHolderLoading) holder;
viewHolderLoading.progressBar.setIndeterminate(true);
}
}
/**
* Get the number of items in the adapter
* @return the number of items in the adapter
*/
@Override
public int getItemCount() { return videosBigSizeList.size(); }
public void setLoaded() {
isLoading = false;
}
/**
* Determine a maximum number of characters for the Title and Channel Name
* If they are too big and the width of the screen is too small, the text
* will get bigger than the thumbnail and then the layout will be disturbed.
* @param videoTitle the title of the video
* @param channelName the name of the channel who uploaded the video
* @param context the activity context
*/
private void setTextMaxLength(TextView videoTitle, TextView channelName, Context context) {
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
if (windowManager != null) {
// Get the current width of the screen in DP
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
// 1) If the device is 420dp or less;
// 2) Limit the number of characters for the title and channel name
if (dpWidth <= 420) {
videoTitle.setFilters(new InputFilter[]{new InputFilter.LengthFilter(35)});
channelName.setFilters(new InputFilter[]{new InputFilter.LengthFilter(25)});
}
}
}
}
ProfileFragment.java
private void setupRecyclerView(final List<VideosBigSize> userAllVideosList) {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setNestedScrollingEnabled(false);
final RecyclerAdapterSmallVideos adapterSmallVideos = new RecyclerAdapterSmallVideos(mRecyclerView, mContext, userAllVideosList);
mRecyclerView.setAdapter(adapterSmallVideos);
// Set Load more event
adapterSmallVideos.setLoadMore(new ILoadMore() {
@Override
public void onLoadMore() {
if (userAllVideosList.size() <= 50) {
mRecyclerView.post(new Runnable() {
@Override
public void run() {
userAllVideosList.add(null);
adapterSmallVideos.notifyItemInserted(userAllVideosList.size() - 1);
}
});
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
userAllVideosList.remove(userAllVideosList.size() - 1);
adapterSmallVideos.notifyItemRemoved(userAllVideosList.size());
// Random more data
int index = userAllVideosList.size();
int end = index + 10;
for (int i = index; i < end; i++) {
// Add more data to userAllVideosList...
adapterSmallVideos.notifyItemInserted(i);
}
adapterSmallVideos.setLoaded();
}
}, 2000);
}
// Loaded everything already
else {
Toast.makeText(mContext, "Load data completed!", Toast.LENGTH_SHORT).show();
}
}
});
}
我的 ProfileFragment 布局
fragment_profile.xml
值得注意的是:
1) 我的 Recycler View 位于 NesteScrollView 内部,因为我需要隐藏/显示工具栏。记住我设置了 mRecyclerView.setNestedScrollingEnabled(false) 因为它会触发 NestedScrollView;
2)除了回收器 View 之外,我的布局中还有更多内容。
最佳答案
您应该使用分页库来做到这一点,click to see the best tutorial :
And the Github source code of the tutorial
事实证明,因为分页库是一个新功能,所以我只找到了 Kotlin 教程。然后我发现这可能是用 Java 编写的最好的一个。真的很感谢作者,我为此奋斗了整整一个月。
关于android - onScrolled 在用户不滚动的情况下被调用(回收器 View 无限滚动),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50777702/
我正在构建一个我想要的 FragmentPagerAdapter(带有小图标的那个); 到屏幕中间(水平)的第一个项目 滑动它并使它们向左/向右移动屏幕的五分之一 实现此目标的最佳方法是什么? 这是一
我正在使用 GalleryView 和大约 40 张图片,而且速度很慢,因为没有回收... 任何人都可以向我展示在 getView 方法上对 GalleryView 的基本回收。 public cla
我收到警告 This FragmentManager should be recycled after use with #recycle() 我正在尝试修复它。有什么建议吗? date.setOnC
已结束。此问题不符合 Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 a specific programming problem, a software a
是否可以在 global.asax 中捕获回收事件? 我知道 Application_End 会被触发,但有没有办法知道它是由应用程序池的回收触发的? 谢谢,Lieven Cardoen 又名 Joh
当我第一次启动应用程序时,我以正确的方式获得了抽屉导航。当我向下滚动抽屉时,问题就出现了。元素开始消失,其中一些甚至交换了位置。我试图找出问题所在,但找不到。希望你能帮助我。 我已经使用 getIte
我正在尝试构建一个 Android 应用程序,在其中使用 RecyclerView。 在 RecyclerView 的项目中,我使用一个 TextView 和四个 CheckBox 来选择任何人。 现
回收 IIS7 应用程序池是否会终止任何当前正在执行的请求?还是等待所有请求完成(如排水管停止)? 我不希望回收规则导致我的 WCF 站点出现间歇性错误。 谢谢 最佳答案 不。 By default,
我动态创建 div,并希望通过检查 div 的 ID 以正确的顺序放置新的 div。 创建新数据时,我对数组进行排序并创建一个新的 div 容器。第一次构建 DOM 时,它工作正常,因为我先创建数据,
IIS 中 Web 应用程序的 .net Recycle 的 Java 等价物是什么。 这是在 IIS 之外的 Linux 机器上使用 Java 时的情况。 只是停止和启动应用程序吗? 最佳答案 并非
问题: 假设您的传输速度高达 10 MB/s,那么回收 DatagramPacket 对象(而不是每次发送数据包时创建一个新对象)是否是一个好主意? 故事: 我正在创建一个 LAN 文件同步应用程序,
我已经使用适配器创建了一个 ListView,但唯一的问题是我们使用了不同的布局,因为它是一个消息传递应用程序。我想通过使用 View 回收来提高性能,但不知道如何回收 View 。 是否可以更改 V
我是 Android 初学者,我不明白为什么会这样。 Activity 截图: 一切正常,除非我向下滚动(因此我认为它与回收有关)...所以当我向上滚动并尝试撤消第一篇文章中的投票(红色箭头)时,它认
我在 RecyclerView 中使用 FlexboxLayoutManager,我需要阻止 RV 回收。我尝试将 itemViewCacheSize() 设置为项目总数,但没有帮助。我也尝试将 ma
在我使用 SearchView 搜索项目后尝试从 RecyclerView 中删除项目时遇到问题,而如果我不使用 SearchView 并正常删除该项目,它工作正常。 这是一个示例,我正在删除该项目,
我正在尝试动态更改 RecycleView 中的图像。它将成功更改但是当我滚动 RecycleView ImageView 时将更改 这是我的适配器类代码: public class Recycler
我有一个表格如下 |GroupID | UserID | -------------------- |1 | 1 | |1 | 2 | |1 |
大家好,在我的 Activity 布局中,我使用这个 XML 来获取按钮数组
我有一个动画时钟,目前有内存泄漏。我目前似乎能够将东西放在图像之上,但不能将其取走或必须清除它(除了重新绘制整个时钟以使秒针不在两个不同的位置之外)。 用于清除时钟组件的代码是: for(UIView
我正在尝试创建一个简单的动画,在 JavaFX 2.x 中将圆向左移动一个像素,该动画有效,但每当我尝试第二次启动时,它就不再起作用了。我尝试了几种方法,代码如下: public void handl
我是一名优秀的程序员,十分优秀!