[英]RecyclerView not calling onCreateViewHolder or onBindView
沒有收到任何錯誤,所有數據似乎都有效。 由於某種原因,調用了與視圖相關的方法。 我已確定以下內容:
getItemCount() 是唯一被調用的適配器方法,它返回一個正整數值,(我知道這將是你們會關注的領域)
正在調用構造函數,成員變量有效。
Parent View是一個垂直的LinearLayout; 沒有滾動視圖,或任何其他具有自己滾動屬性的視圖。
包含片段視圖被創建並顯示在屏幕上。
這是片段中的聲明,后面是適配器。 任何幫助將不勝感激,因為這完全令人困惑。
SubMenuAdapter adapter = new SubMenuAdapter(getActivity(), mContentItems);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
public class SubMenuAdapter extends RecyclerView.Adapter<SubMenuAdapter.ViewHolder> {
private static final String TAG = String.format("==> %S", SubMenuAdapter.class.getSimpleName());
private final List<ContentItem> mContentItems;
private Context mContext;
public SubMenuAdapter(Context context, List<ContentItem> contenItems) {
Log.d(TAG, "Constructor called");
mContentItems = contenItems;
mContext = context;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.d(TAG, "onCreateViewHolder called");
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_resource_efficiency, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder called");
ContentItem item = mContentItems.get(position);
holder.textName.setText(item.getName());
FontSetter.setMyriadProRegular(mContext, holder.textName);
Picasso.with(mContext).load("file://" + item.getPreviewImageDefault()).into(holder.imageIcon);
}
@Override
public int getItemCount() {
Log.d(mContext, String.format("getItemCount: %d", mContentItems.size()));
return mContentItems.size();
}
// ViewHolder
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView textName;
ImageView imageIcon;
public ViewHolder(View view) {
super(view);
textName = (TextView) view.findViewById(R.id.tv_resource_efficiency_option);
imageIcon = (ImageView) view.findViewById(R.id.iv_resource_efficiency_icon);
}
}
這也可能對某人有所幫助
首次使用
recyclerView.setAdapter(adapter);
進而:
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
所以它看起來像這樣:
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
順序顛倒了
更新:
現在我只是使用:
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
在 xml 中的RecyclerView
上
追了一個多小時的答案。
在設置適配器之前,不要忘記調用此襯墊。
recyclerView.setLayoutManager(new LinearLayoutManager(this));
似乎回收器視圖沒有內置默認布局管理器選項,因此我們必須以編程方式添加它。
如果您覺得有幫助,請干杯。
確保回收視圖不是來自nestedscrollview 的子視圖
例如,此代碼將不起作用。
<android.support.v4.widget.NestedScrollView
android:id="@+id/responder_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/darkGray"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
app:cardElevation="@dimen/spacing_medium"
app:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/responder_testimonial"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Testimonial"
android:textSize="@dimen/general_font_size" />
<TextView
android:id="@+id/responder_counter_testimonial"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/responder_testimonial"
android:text="170"
android:textSize="@dimen/general_font_size_small" />
<Button
android:id="@+id/responder_btn_testimonial"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Go" />
<view
android:id="@+id/responder_list_testimonial"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/responder_testimonial"
class="android.support.v7.widget.RecyclerView"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
</android.support.v4.widget.NestedScrollView>
然后我用,
<android.support.design.widget.CoordinatorLayout
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:fitsSystemWindows="true">
<view
android:id="@+id/responder_list_testimonial"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/responder_testimonial"
class="android.support.v7.widget.RecyclerView"/>
我不知道這是否對任何人都有幫助,但我幾乎遇到了同樣的問題。 我的問題不在於片段/類,也不在於回收器適配器。 問題出在父 XML 布局中,其中操作FrameLayout
采用了match_parent
,其中FrameLayout
片段被替換的地方)沒有任何可用的位置來顯示。 這就是沒有調用這些方法的原因。
我想那些面臨同樣問題的人可能會遇到類似的情況。 仔細檢查每個 XML 文件中的每個寬度和高度可能在同一棵樹中,因為問題似乎根本不在適配器中。
我的兩便士在這里。 只花了三個多小時調試這個。
確保您沒有不小心使用以下行。
recyclerView.setHasFixedSize(true);
僅當您確定視圖具有恆定大小時才設置固定大小。 如果不是,則可能根本不會調用 onCreateViewHolder 和 onBindView 方法。
我也遇到了同樣的問題,即onCreateViewHolder
或onBindView
方法沒有被調用,只有getItemCount
被調用。 所以基本上是RecyclerView
的高度和重量設置為wrap_content
或0dp
。 將其更改為某個值后解決了問題。
這已經很老了,但就我而言,我使用的是ConstraintLayout
並且高度設置錯誤,因此我的視圖將具有0dp
,然后適配器將保存以完成其工作,因為視圖是 0dp。
確保高度和寬度正常並且RecyclerView
具有正大小。
如果您將 wrap_content 作為列表的高度以及項目列表的高度,則不會顯示任何內容並且不會調用任何 recyclerView 函數。
就我而言,在將 Activity 更改為 ViewModel 並使用 Binding 后,我忘記從onCreate
方法中刪除setContentView
。 通過刪除它,我的問題解決了。
在實現 FirebaseListAdapter 時,需要注意以下幾點才能正確設置。
注意 -使用 wrap_content 作為 recyclerview 的高度是任何人都可能犯的最簡單的錯誤之一。 所以一定要先檢查一下。
我知道這個話題很老,但如果你和我一樣犯了同樣的學習錯誤,你可能會發現這很有幫助。
當我在一些關於 RecyclerView 的網站上學習並復制一些代碼並適應我的上下文時,我創建了不同的變量(例如用戶和數據),它們旨在做同樣的事情,除了一些方法調用數據,一些方法調用用戶. 當您試圖理解其他人的代碼和 Java 功能時,這是一個很容易犯的錯誤(它一直發生在我身上)。
很高興知道您可以在 Java 代碼的任何位置在控制台中 println,因此您可以非常輕松地進行調試。
祝你好運!
就我而言,它使用的是 setHasStableIds(true); 在適配器中,而某些列表項在 getItemID() 中返回 -1,所以我想 RecyclerView 認為它們是相等的。
在我的情況下,有一個Fragment
與RecyclerView
一個內部ViewPager
。 出現問題是因為我使用Fragment.getFragmentManager()
而不是Fragment.getChildFragmentManager
作為FragmentStatePagerAdapter
的構造函數。
PS Using Layout Inspector 可能對調試此類問題有很大幫助。
請注意您正在使用適配器的線程。
在我的情況下,問題是當我的數據來自服務時從活動中調用notifyDataSetChanged()
。 實際上該方法是從后台線程調用的。 但是應用程序沒有崩潰,Logcat (!) 中什么也沒有。
所以我在 UI 線程中被稱為notifyDataSetChanged()
並且問題解決了。
runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
}
});
就我而言,我將回收器視圖適配器設置為recyclerview.apply { adapter = adapter }
兩者都指的是 getAdapter() 因此將我的適配器變量名稱重命名為 folderAdapter
如果將 viewpager 放在滾動視圖中,有時會出現此錯誤,這將縮小父視圖以及 viewpager 及其子片段。 因此,如果現在要為子片段找到視圖,則不會調用 onCreateView 和 onBindView 方法。 只需刪除滾動視圖或為您的布局添加權重,這樣視圖就不會縮小。
我有同樣的問題,既沒有調用 onCreateViewHolder 也沒有調用 onBindViewHolder 。 更改您的 onCreateViewHolder 方法以使用您在構造函數中保存引用的 Context 而不是執行 parent.getContext() 應該修復它:
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.d(TAG, "onCreateViewHolder called");
View view = LayoutInflater.from(mContext).inflate(R.layout.row_resource_efficiency, parent, false);
return new ViewHolder(view);
就我而言,我將 RecyclerView 的 ID 設置為“recyclerView”。 這個 ID 似乎已經在某處定義了,因為當我將它更改為不同的 ID 時,來自適配器的方法被正確調用。
我最近遇到了這個問題,顯然有很多可能的原因。 嘗試這些選項中的一個或組合,看看哪一個適合你:)
1. 布局管理器
確保您將布局管理器設置為您的回收站視圖,如下所示
// create a layout manager
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(my_context);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
// get recycler view
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_id);
// set
recyclerView.setLayoutManager(linearLayoutManager);
2. 固定尺寸
確保您說明您的回收站視圖是否具有固定大小
// set fixed size
recyclerView.setHasFixedSize(true); // or false depending on implementation
3. XML
確保你的回收器沒有嵌套在太多可能導致混淆的布局中,例如 ScrollView 和 RelativeLayout 的組合。 簡單點,看看能不能解決你的問題
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/thread_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
如果在設置 recyclerview 高度以匹配父級 (0) 時使用約束布局,則會出現此問題
我有以下情況:
@Override
protected void onStart() {
super.onStart();
Log.d("OnStart","Calling OnStart.");
FirebaseRecyclerOptions<Data> options = new FirebaseRecyclerOptions.Builder<Data>().setQuery(mDatabase, new SnapshotParser<Data>() {
@NonNull
@Override
public Data parseSnapshot(@NonNull DataSnapshot snapshot) {
Log.d("parseSnapshot",snapshot.child("name").getValue().toString());
return new Data(snapshot.child("name").getValue().toString(),
snapshot.child("description").getValue().toString(),
snapshot.child("id").getValue().toString(),
snapshot.child("date").getValue().toString());
}
}).build();
FirebaseRecyclerAdapter<Data,MyViewHolder> adapter = new FirebaseRecyclerAdapter<Data, MyViewHolder>(options) {
@Override
protected void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i, @NonNull Data data) {
Log.d("OnBindViewHolder",data.getName());
myViewHolder.setName(data.getName());
myViewHolder.setDescription(data.getDescription());
myViewHolder.setDate(data.getDate());
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Log.d("OnCreateViewHolder","Creating the viewHolder");
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemlayout,parent,false);
return new MyViewHolder(view);
}
};
recyclerView.setAdapter(adapter);
Log.d("OnStart","Exiting OnStart.");
}
和 OnCreateViewHolder 和 OnBindViewHolder 沒有被調用。
就我而言,我一直在使用分頁庫和 PagingDataAdapter。 在所有數據都已經從 PagingSoure 中獲取並且 RecyclerView 沒有顯示任何內容之后,我設置了一個適配器。 我通過在設置適配器后調用adapter.refresh()
解決了這個問題。 像這樣:
recyclerView.adapter = myAdapter
myAdapter.refresh()
我有同樣的問題。 在我的情況下,recyclerView 在幾次刷新后變空了。 例如,當我單擊一個項目並從另一個活動中返回時。 我有數據,但數據沒有設置為 recyclerView 並且沒有錯誤。
我在onCreate方法上創建了 recyclerView,如下所示:
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
binding.recyclerCommodityList2.setLayoutManager(staggeredGridLayoutManager);
binding.recyclerCommodityList2.addItemDecoration(new GridSpacingItemDecoration(2, 0, true));
adapterCommodityList = new RecyclerAdapterMyCommoditiAndPost(cardList.getCard(), context);
binding.recyclerCommodityList2.setAdapter(adapterCommodityList);
binding.recyclerCommodityList2.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NotNull RecyclerView recyclerView, int dx, int dy) {
visibleItemCount = staggeredGridLayoutManager.getChildCount();
totalItemCount = staggeredGridLayoutManager.getItemCount();
if (dy > 0) { //check for scroll down
pastVisibleItems = staggeredGridLayoutManager.findFirstVisibleItemPositions(null)[1];
if ((visibleItemCount + pastVisibleItems) >= totalItemCount / 2 ) {
if (loading) {
loading = false;
callGetListOfCommodity(selectedCategory); // call api again
}
}
}
}
});
我將數據放在 api onResponse 方法上,如下所示:
adapterCommodityList = new RecyclerAdapterMyCommoditiAndPost(result.getCard(), MyTamukActivity.this);
binding.recyclerCommodityList2.setAdapter(adapterCommodityList);
所以我在 onResponse 方法上坐了一個新的布局管理器。 像這樣 :
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
binding.recyclerCommodityList2.setLayoutManager(staggeredGridLayoutManager);
adapterCommodityList = new RecyclerAdapterMyCommoditiAndPost(result.getCard(), MyTamukActivity.this);
binding.recyclerCommodityList2.setAdapter(adapterCommodityList);
該解決方案有效,但有時 recyclerView 仍然為空。
所以這是我的最終解決方案:
我從 onCreate 中刪除了 recyclerView 然后我在onResume方法上創建了 recyclerView 而不是那個。 所以布局管理器總是正確地坐在 recyclerView 上。
無論如何,如果您有同樣的問題,請檢查您的布局管理器以及如何在 recyclerView 上設置它。
如果將 recyclerview 放在滾動視圖中,請將滾動視圖替換為 NestedScrollView 並將此行放在 recyclerview 標記中
android:overScrollMode="never"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.