- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在 StackOverflow 中多次看到这个问题,但我无法解决问题。于是伸出援手。
请注意:我已经检查过关于 SO 的其他问题,虽然我可以消除错误,但它还有其他问题。
这是我现有的代码:
我的适配器类:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context context;
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
private IOnLoadMoreListener mIOnLoadMoreListener;
private int visibleThreshold = 3;
private int lastVisibleItem, totalItemCount;
private int[] lastVisibleItems = new int[mStaggeredLayoutManager.getSpanCount()];
public RecyclerViewAdapter(Context context) {
this.context = context;
final StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
totalItemCount = staggeredGridLayoutManager.getItemCount();
lastVisibleItems = staggeredGridLayoutManager.findLastVisibleItemPositions(new int[mStaggeredLayoutManager.getSpanCount()]);
if (staggeredGridLayoutManager.getSpanCount() == 1) {
lastVisibleItem = lastVisibleItems[0];
} else if (staggeredGridLayoutManager.getSpanCount() == 2) {
lastVisibleItem = Math.max(lastVisibleItems[0], lastVisibleItems[1]);
} else if (staggeredGridLayoutManager.getSpanCount() == 3) {
lastVisibleItem = Math.max(Math.max(lastVisibleItems[0], lastVisibleItems[1]), lastVisibleItems[2]);
}
if (!isRefreshing && totalItemCount <= lastVisibleItem + visibleThreshold) {
if (mIOnLoadMoreListener != null) {
mIOnLoadMoreListener.onLoadMore();
}
isRefreshing = true;
}
}
});
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_ITEM) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_recyclerview_shop_fragment, parent, false);
return new CustomViewHolder(v);
} else if (viewType == VIEW_TYPE_LOADING) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_recyclerview_loading_shop_fragment, parent, false);
return new LoadingViewHolder(v);
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Product item = listItems.get(position);
if (holder.getItemViewType() == VIEW_TYPE_ITEM) {
CustomViewHolder customViewHolder = (CustomViewHolder) holder;
Glide.with(context).load(item.getFeaturedSrc()).into(customViewHolder.imageView);
} else if (holder.getItemViewType() == VIEW_TYPE_LOADING) {
if (holder instanceof LoadingViewHolder) {
LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
loadingViewHolder.progressBar.setIndeterminate(true);
}
}
}
@Override
public int getItemCount() {
return listItems == null ? 0 : listItems.size();
}
@Override
public int getItemViewType(int position) {
if (listItems.get(position) == null) {
return VIEW_TYPE_LOADING;
} else {
return VIEW_TYPE_ITEM;
}
}
public void setOnLoadMoreListener(IOnLoadMoreListener mIOnLoadMoreListener) {
this.mIOnLoadMoreListener = mIOnLoadMoreListener;
}
public class CustomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView imageView;
TextView textView;
String id;
public CustomViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
imageView = (ImageView) itemView.findViewById(R.id.imageView_thumbnail);
}
@Override
public void onClick(View v) {
int position = getAdapterPosition();
}
}
public class LoadingViewHolder extends RecyclerView.ViewHolder {
public ProgressBar progressBar;
public LoadingViewHolder(View progressView) {
super(progressView);
progressBar = (ProgressBar) progressView.findViewById(R.id.progressBar);
}
}
}
我以前的代码:
mRecyclerViewAdapter.setOnLoadMoreListener(new IOnLoadMoreListener() {
@Override
public void onLoadMore() {
listItems.add(null);
mRecyclerViewAdapter.notifyItemChanged(listItems.size() - 1);
mRecyclerViewAdapter.notifyDataSetChanged();
isProgressVisible = true;
getDataFromServer(false);
}
});
使用我的旧代码,我得到以下 IllegalStateException:
W/RecyclerView: Cannot call this method in a scroll callback. Scroll callbacks mightbe run during a measure & layout pass where you cannot change theRecyclerView data. Any method call that might change the structureof the RecyclerView or the adapter contents should be postponed tothe next frame.
java.lang.IllegalStateException:
at android.support.v7.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:2581)
at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onItemRangeChanged(RecyclerView.java:4943)
at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyItemRangeChanged(RecyclerView.java:11373)
at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyItemRangeChanged(RecyclerView.java:11364)
at android.support.v7.widget.RecyclerView$Adapter.notifyItemChanged(RecyclerView.java:6652)
at codsiga.com.xx.ShopFragment$1.onLoadMore(ShopFragment.java:148)
at codsiga.com.xx.ShopFragment$RecyclerViewAdapter$1.onScrolled(ShopFragment.java:229)
at android.support.v7.widget.RecyclerView.dispatchOnScrolled(RecyclerView.java:4618)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep3(RecyclerView.java:3679)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3323)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3844)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:636)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1795)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:131)
at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1391)
at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:870)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
03-22 11:36:32.083 3189-3189/codsiga.com.xx W/RecyclerView:
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:726)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2346)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2068)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:621)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
因此,根据各种 StackOverflow 答案的建议,我将其修改如下:
查看各种答案的修改代码:
mRecyclerViewAdapter.setOnLoadMoreListener(new IOnLoadMoreListener() {
@Override
public void onLoadMore() {
recyclerView.post(new Runnable() {
@Override
public void run() {
listItems.add(null);
mRecyclerViewAdapter.notifyItemChanged(listItems.size() - 1);
mRecyclerViewAdapter.notifyDataSetChanged();
isProgressVisible = true;
getDataFromServer(false);
}
});
}
});
现在,我没有收到错误消息,但是 onLoadMore()
被调用了两次,每次都会刷新 recyclerview 中的 View 。我做错了什么?请查看 logcat 输出:
D/xx: Response => {…}
D/xx: Length = 9
D/xx: Query 'SELECT * FROM products' returned 9 rows
D/xx: Response => {…}
D/xx: Length = 9
D/xx: Query 'SELECT * FROM products' returned 18 rows
最佳答案
Cannot call this method in a scroll callback. Scroll callbacks mightbe run during a measure & layout pass where you cannot change theRecyclerView data. Any method call that might change the structureof the RecyclerView or the adapter contents should be postponed tothe next frame.
警告本身就是一种解释。 换句话说,您正在更新 View ,而 recyclerview 正在计算布局尺寸。
哪里出了问题?下面的实现 -
mRecyclerViewAdapter.notifyItemChanged(listItems.size() - 1);
mRecyclerViewAdapter.notifyDataSetChanged();
您可以做的是将此 UI 操作发送到下一个 UI 框架。您可以通过调用 View.post()
方法来完成此操作。
recyclerView.post(new Runnable() {
public void run() {
// There is no need to use notifyDataSetChanged()
mRecyclerViewAdapter.notifyItemInserted(allArticles.size() - 1);
}
});
关于android - Recyclerview - 无法在滚动回调中调用此方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42944005/
我在另一个 RecyclerView(parentRecyclerView) 中实现了 RecyclerView(childRecyclerView),图片说明了所有的实现: 我想编写一个 espre
我正在构建一个应用程序,它使用ViewPager2在页面之间水平滚动,每个页面都有一个垂直滚动的内容RecyclerView,其中每个列表的第一个位置都有一行水平滚动小部件,例如附加到寻呼机指示器类型
我正在尝试实现一个水平的 recyclerview 并且 recyclerview 的每个项目都将是一个具有网格布局的垂直 recyclerview。我面临的问题是,当我尝试垂直滚动子 recycle
我使用显示条目列表的 RecyclerView。每个条目都托管另一个 RecyclerView,它是一个图像列表。 我现在想让这个嵌套的 RecyclerView 可点击,而不是它的项目,而是整个 V
我正在尝试将手机中的图像加载到我的回收 View 中。 到目前为止,我已经创建了一个 recyclerview.adapter 和一个 gridlayoutmanager,并将它们附加到我的 recy
我需要一个可扩展 View ,其中父/可扩展标题将具有文本和下拉箭头。每个此类标题的子项应该是在网格结构中具有多个项目的 View 。 (有点像带有 GridLayoutManager 的回收器 Vi
我正在使用显示不同类别列表的 RecyclerView。每行项目还包含 RecyclerView 以显示类别项目列表。父级 RecyclerView 由垂直 LinearLayoutManager 填
我正在更新一个旧的 Android 项目,现在我从 RecyclerView 中反复收到这条日志语句: W/RecyclerView:RecyclerView 不支持滚动到绝对位置。改为使用 scro
在我的 Adapter 中,我调用 LayoutManager.ChildAt(position) 来获取 itemview,但是我得到的 View 不是匹配的 itemview,当我调用 notif
我正在从 ListView 迁移到 RecyclerView,但是在 SQLite 中输入一些数据后,我的列表没有使用 notifyDataSetChanged() 更新;所以我总是要调用setAda
我正在用 Google Now Cards 的风格创建一组 5 张卡片。我首先关注的是总体布局。 我正在使用 CardView 和 RecyclerView ,我想要实现的是这样的: 这是我的 Car
在我的应用程序中,我有一个 RecyclerView,其中包含一个简单的项目 View ,每行包含一个 TextView 和一个 Spinner。 用户从操作栏中单击“保存”后,我需要遍历所有项目并获
我正在尝试检查 RecyclerView 中是否可以看到某些特定项目;但我无法实现。请帮助我确定我的项目是否在 RecyclerView 中完全可见。 mrecylerView.addOnScroll
我有一个提要片段,它的主要元素是帖子的 RecyclerView。 我正在使用 Lisa Wray 的 Groupie 库管理回收站 https://github.com/lisawray/group
我有这两个类似的行为回收器 View 适配器,它们之间的唯一区别是 onclick 方法和传递给它们的对象。所以,我正在考虑将类 B 设计为从回收器 View 适配器继承,这样我就可以更改构造函数来执
这很奇怪。我对这个问题感到沮丧。我将数据保存在 ArrayList 中。当我将数据放在 RecyclerView 上时。数据未显示在列表中。这是我的代码 listOrder.forEach { ord
编辑我通过使用 CoordinatorLayout 和 AppBarLayout 作为 header 和 TabLayout 的包装解决了这个问题。本来应该很明显,但是哦,好吧。 原始问题:我有一个设
我有一个回收 View 。我想从其适配器类更新回收器 View 。我尝试了 notiftDataSetChanged( ) 但它只适用于主类。下面是 recyclerview 适配器类的代码。 pac
我正在使用具有不同 viewholders 的 recyclerview(具有垂直 LinearLayout),其中一个有另一个 RecyclerView(带有水平 LL)。在第二个 recycler
我想创建一个与 Google Play Store 或 Netflix App 类似的布局,其中在单个 RecyclerView 中基本上有多个水平 RecyclerView。如果这不是他们做事的方式
我是一名优秀的程序员,十分优秀!