Win*_*Oak 41 android android-recyclerview
我在我的应用程序中使用了RecyclerView支持,我看到了最奇怪的事情.在我触摸滚动之前,它不会显示任何项目.然后,突然之间,RecyclerView会自行填充.我已经确认填充了支持适配器的列表,并且在触摸事件之前永远不会调用onCreatViewHolder和onBindViewHolder.
以下是我设置recyclerview的方法:
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
Drawable divider = new ColorDrawable(ProfileInfo.getCurrentProfileColor());
mInboxList.addItemDecoration(new DividerItemDecoration(getActivity(), divider, false));
mInboxList.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
mInboxList.setAdapter(new InboxAdapter(getActivity(), new ArrayList<Conversation>()));
new AsyncTask<Void, Void, List<Conversation>{
public List<Conversation> doInBackground(...){
//load the conversations
return conversations;
}
public void onPostExecute(List<Conversation> conversations){
((InboxAdapter) mInboxList.getAdapter()).clear(false);
((InboxAdapter) mInboxList.getAdapter()).addAll(conversations);
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
Run Code Online (Sandbox Code Playgroud)
这是我的适配器的要点:
public class InboxAdapter extends RecyclerView.Adapter<InboxAdapter.ViewHolder> {
List<Conversation> mConversations; //initialized in contructor
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = mInflater.inflate(R.layout.inbox_item, parent, false);
ViewHolder holder = new ViewHolder(v);
Log.d(LOG_TAG, "oncreateviewholder : " + viewType); //never called when I first bind the adapter
return holder;
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final Conversation item = mConversations.get(position);
Log.d(LOG_TAG, "binding " + position);
...
}
@Override
public int getItemCount() {
Log.d(LOG_TAG, "item count: " + mConversations.size());
return mConversations.size();
}
/**
* Empties out the whole and optionally notifies
*/
public void clear(boolean notify) {
mConversations.clear();
if (notify) {
notifyDataSetChanged();
}
}
public void addAll(List<Conversation> conversations) {
mConversations.addAll(conversations);
notifyDataSetChanged();
}
}
Run Code Online (Sandbox Code Playgroud)
这是布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize">
<android.support.v7.widget.RecyclerView
android:id="@+id/lv_inbox"
android:layout_width="match_parent"
android:layout_height="match_parent"
></android.support.v7.widget.RecyclerView>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
我正在使用版本4.4.4的Moto X上运行的recyclerview-v7:21.0.3.
编辑: 在onPostExecute结束时平滑滚动似乎解决了这个问题:
if (mInboxList.getAdapter().getItemCount() > 0) {
mInboxList.smoothScrollToPosition(0);
}
Run Code Online (Sandbox Code Playgroud)
如果其他人使用RxJava和Retrofit遇到此问题,我通过.observeOn(AndroidSchedulers.mainThread())
在订阅之前将操作符添加到我的方法链中来解决此问题.我读过这个是默认处理的,因此没有明确的必要,但我猜不是.希望这可以帮助.
例:
public void loadPhotos() {
mTestPhotoService.mServiceAPI.getPhotos()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(photoList -> mRecyclerActivity.OnPhotosLoaded(photoList));
}
Run Code Online (Sandbox Code Playgroud)
在我的情况下,只有这样有效:
recyclerView.smoothScrollToPosition(arrayModel.size-1); // I am passing last position here you can pass any existing position
Run Code Online (Sandbox Code Playgroud)
RecyclerView 仅在我滚动它时才显示数据。因此,代替用户手动滚动,我在上面添加了以编程方式滚动 recyclerView 的行。
所以一开始,就像我刚刚添加的其他人一样:
recyclerView.smoothScrollToPosition(0)
Run Code Online (Sandbox Code Playgroud)
它工作得非常好,但是它并不好,您必须记住每次都添加它。然后我跟着@SudoPlz 评论并回答了另一个问题,它也有效,您必须扩展 RecyclerView 并覆盖 requestLayout:
private boolean mRequestedLayout = false;
@SuppressLint("WrongCall")
@Override
public void requestLayout() {
super.requestLayout();
// We need to intercept this method because if we don't our children will never update
// Check /sf/ask/3456030651/
if (!mRequestedLayout) {
mRequestedLayout = true;
this.post(() -> {
mRequestedLayout = false;
layout(getLeft(), getTop(), getRight(), getBottom());
onLayout(false, getLeft(), getTop(), getRight(), getBottom());
});
}
}
Run Code Online (Sandbox Code Playgroud)
尽管如此,我还是希望在 4、5 年后修复它,但是,这是一个很好的解决方法,您不会忘记它们。
Mar*_*hre -3
这很可能是因为您没有调用 RecyclerView.Adapter 的正确通知方法。与之前在 ListAdapters 中的界面相比,您拥有更精细的界面。例如,在 addAll() 中,您应该调用notifyItemRangeInserted(oldConversationsSize, conversations.size())
而不是notifyDataSetChanged
归档时间: |
|
查看次数: |
4665 次 |
最近记录: |