Recyclerview 不调用任何 Adapter 方法:onCreateViewHolder,onBindViewHolder,
Recyclerview not call any Adapter method :onCreateViewHolder,onBindViewHolder,
我的RecyclerView没有调用onCreateViewHolder、onBindViewHolder,所以在recyclerview中没有出现nothing。我把日志用于调试,并没有显示日志。可以是什么?
我的适配器:
public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private static final int EMPTY_VIEW = 10 ;
private ArrayList<comment> mItems;
Boolean firstTime = true;
private Typeface mTf = null;
Context mContext;
public CommentListAdapter(Context context,ArrayList<comment> items){
Log.e("Adapter", "constructor Called");
this.mItems = items;
mContext = context;
}
public class EmptyViewHolder extends RecyclerView.ViewHolder {
public EmptyViewHolder(View itemView) {
super(itemView);
}
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView mAuthorName;
TextView mMessage;
NetworkImageView mThumbnail;
public ViewHolder(View itemView) {
super(itemView);
mAuthorName = (TextView)itemView.findViewById(R.id.author_name);
mMessage = (TextView)itemView.findViewById(R.id.message);
mThumbnail = (NetworkImageView)itemView.findViewById(R.id.author_avatar);
}
}
public void add(comment item, int position) {
mItems.add(position, item);
notifyItemInserted(position);
}
public void remove(comment item) {
int position = mItems.indexOf(item);
mItems.remove(position);
notifyItemRemoved(position);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
Log.e("Adapter", "onCreateViewHolder Called");
View v;
if(firstTime){
mTf = BBcTypeFace.getTypeFace(parent.getContext().getApplicationContext(),"font/bbc.ttf");
firstTime = false;
}
if( viewType == EMPTY_VIEW){
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.comment_empty_row,parent,false);
EmptyViewHolder evh = new EmptyViewHolder(v);
return evh;
}else {
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.comment_row, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
Log.e("Adapter", "onBindViewHolder Called");
if(viewHolder instanceof ViewHolder) {
ViewHolder holder = (ViewHolder)viewHolder;
comment c = mItems.get(position);
Log.e("Adapter", "Comment is\n: " + c.toString());
final ViewHolder finalHolder = holder;
ImageRequest request = new ImageRequest(c.author_img_link, new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {
if (bitmap != null) {
finalHolder.mThumbnail.setImageBitmap(bitmap);
}
}
}, 0, 0, null,
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
VolleyLog.e("ImageLoader", volleyError.getMessage());
VolleyLog.e("ImageLoader", volleyError.getStackTrace());
}
});
GetVideoInfo.getInstance(mContext.getApplicationContext()).addToRequestQueue(request);
holder.mAuthorName.setText(c.author_name);
holder.mMessage.setText(c.Message);
holder.mMessage.setTypeface(mTf);
holder.mAuthorName.setTypeface(mTf);
}
}
@Override
public int getItemCount() {
Log.e("Adapter", "getItemCount() Called");
return (mItems.size() > 0 ? mItems.size() : 1);
}
@Override
public int getItemViewType(int position) {
Log.e("Adapter", "getItemViewType() Called");
if (mItems.size() == 0) {
return EMPTY_VIEW;
}
return super.getItemViewType(position);
}}
我将使用 public void add(comment item, int position){...}
在 RecyclerView 中添加项目。
在片段中:
private RecyclerView mRecyclerView;
private CommentListAdapter mAdapter;
private LayoutManager mLayoutManager;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_detail, container, false);
....
mLayoutManager = new LinearLayoutManager(getActivity());
mAdapter = new CommentListAdapter(getActivity(),new ArrayList<comment>());
mRecyclerView = (RecyclerView)rootView.findViewById(R.id.comment_list);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
makeJsonObjectRequest(mItem.url);
return rootView;
}
XML 个文件:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/scrollView"
android:background="@android:color/white"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true">
....
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
.....
<android.support.v7.widget.RecyclerView
android:id="@+id/comment_list"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
....
</RelativeLayout>
....
</ScrollView>
comment_row xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="horizontal"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:gravity="right"
android:background="@android:color/darker_gray">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/author_name"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/author_avatar"
android:layout_toStartOf="@+id/author_avatar"
android:gravity="right" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/message"
android:layout_below="@+id/author_name"
android:layout_toLeftOf="@+id/author_avatar"
android:layout_toStartOf="@+id/author_avatar"
android:gravity="right" />
</LinearLayout>
<com.android.volley.toolbox.NetworkImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/author_avatar"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:minHeight="150dp"
android:minWidth="150dp" /></LinearLayout>
我将使用此代码将项目添加到 RecyclerView :
JsonObjectRequest jsonObjReqComment = new
JsonObjectRequest(Request.Method.GET,urlJsonObj+"#comment", null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONArray res = response.getJSONArray("response");
//Log.e("Comment","Count:"+response.toString());
//Log.e("Comment","Count:"+res.length());
for (int i = 0; i < res.length(); i++) {
JSONObject thread = res.getJSONObject(i);
JSONObject author_json = thread.getJSONObject("author");
int dislikes = thread.getInt("dislikes");
int likes = thread.getInt("likes");
String Message = thread.getString("message");
//get Author info
String author_img_link = author_json.getJSONObject("avatar").getString("permalink");
String author_name = author_json.getString("name");
comment c = new comment(dislikes,likes,Message,author_img_link,author_name);
//Log.e("Comment",c.toString());
//commentsList.add(c);
mAdapter.add(c,0);
}
} catch (JSONException e) {
Log.e("OnResponse","Error JSON");
e.printStackTrace();
} catch (Exception e){
Log.e("OnResponse","Error Exception");
e.printStackTrace();
}
}
}
, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("vOLLEY", "Error: " + error.getMessage());
// hide the progress dialog
}
}
){
@Override
public Map<String, String> getHeaders(){
Map<String, String> headers = new HashMap<String, String>();
headers.put("User-agent", "Comment");
return headers;
}
};
由于@yigit 猜测 ScrollView
、RelativeLayout
的组合导致了这个问题,
为 RecyclerView
.
腾出更多空间
If RecyclerView gets put into a ScrollView, then during measure step its height is unspecified (because ScrollView allows any height) and gets equal to minimum height (as per implementation) which is apparently zero.
参考:android: RecyclerView inside a ScrollView
解决方案:
- 将视图放在 RecyclerView 的行中
- 计算列表项的大小并以编程方式设置 ListView 的高度
http://vardhan-justlikethat.blogspot.com/2014/04/android-listview-inside-scrollview.html
除了@SanatiSharif 和@sohrab 的回答,您还必须执行以下强制步骤。
请务必调用 setLayoutManager
,如下所示。
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
在将adapter设置到recyclerView之前,否则无法正常工作。
如果需要,您可以自定义它。
this link 将让您了解 LayoutManager 的工作原理。
来晚了,希望对大家有所帮助。尝试以下任一方法:
第一个解决方案:
确保你没有不必要地使用这一行
recyclerView.setHasFixedSize(true);
第二种解决方案:
确保将布局管理器设置为 recyclerView
recycler.setLayoutManager(new LinearLayoutManager(this));
第三种方案:
你 getItemCount
returns 0,所以 RecyclerView
从不尝试实例化视图。使其 return 大于 0
在我的例子中,我有这个结构
<ScrollView>
<RelativeLayout>
<android.support.v7.widget.RecyclerView/>
</RelativeLayout>
</ScrollView>
我解决了删除 Relative 的问题
<ScrollView>
<android.support.v7.widget.RecyclerView/>
</ScrollView>
可能情况不同,但对我来说,我只是忘记按如下方式设置布局管理器:
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recycler.setLayoutManager(layoutManager);
希望对您有所帮助:)
在我的案例中,我使用的是 Fragment-> ViewPager 和 Tablayout -> Inside viewpagers item 我使用的是 RecyclerView。
所以我没有调用 ViewPagerAdapter(getChildFragmentManager()) ,而是调用了 ViewPagerAdapter(getSupportFragmentManager()) ,这就是为什么我的任何回收器适配器项目都没有被调用的原因。
因此在片段中设置 ViewPagerAdapter 的正确方法是
ViewPagerAdapter(getChildFragmentManager())
有点傻,但另一个可以阻止对方法的调用的是将视图的可见性声明为 GONE。
android:visibility="gone"
recyclerView.setVisibility(View.GONE);
其中任何一个都会阻止 RecyclerView.Adapter
中方法的调用
希望对大家有所帮助。
我遇到了类似的问题,但上述 none 个答案对我有所帮助。
最后,我发现我在为我的 RecyclerView 所在的 Fragment 创建和绑定视图时犯了一个错误:
有问题的代码
FormPageFragment.onCreate
binding=FormPageBinding.inflate(layoutInflater)
但在 onCreateView 中我这样做了:
FormPageFragment.onCreate查看
return inflater.inflate(R.layout.form_page, container, false)
之后在 onStart 中像这样设置适配器:
FormPageFragment.onStart
binding.formContent.adapter=FormEntriesAdapter(page, viewModel.enteredData)
解决方案
但这是垃圾。它应该在 onCreateView 中完成,当然 binding.rootView 需要作为视图 返回,否则绑定视图不会附加到布局并设置任何适配器它们没有效果。
onCreateView 的工作版本
binding=FormPageBinding.inflate(layoutInflater)
return binding.root
因此,与 RecyclerView 本身相比,片段实例化、创建和绑定正确视图的问题更多。
我的RecyclerView没有调用onCreateViewHolder、onBindViewHolder,所以在recyclerview中没有出现nothing。我把日志用于调试,并没有显示日志。可以是什么?
我的适配器:
public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private static final int EMPTY_VIEW = 10 ;
private ArrayList<comment> mItems;
Boolean firstTime = true;
private Typeface mTf = null;
Context mContext;
public CommentListAdapter(Context context,ArrayList<comment> items){
Log.e("Adapter", "constructor Called");
this.mItems = items;
mContext = context;
}
public class EmptyViewHolder extends RecyclerView.ViewHolder {
public EmptyViewHolder(View itemView) {
super(itemView);
}
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView mAuthorName;
TextView mMessage;
NetworkImageView mThumbnail;
public ViewHolder(View itemView) {
super(itemView);
mAuthorName = (TextView)itemView.findViewById(R.id.author_name);
mMessage = (TextView)itemView.findViewById(R.id.message);
mThumbnail = (NetworkImageView)itemView.findViewById(R.id.author_avatar);
}
}
public void add(comment item, int position) {
mItems.add(position, item);
notifyItemInserted(position);
}
public void remove(comment item) {
int position = mItems.indexOf(item);
mItems.remove(position);
notifyItemRemoved(position);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
Log.e("Adapter", "onCreateViewHolder Called");
View v;
if(firstTime){
mTf = BBcTypeFace.getTypeFace(parent.getContext().getApplicationContext(),"font/bbc.ttf");
firstTime = false;
}
if( viewType == EMPTY_VIEW){
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.comment_empty_row,parent,false);
EmptyViewHolder evh = new EmptyViewHolder(v);
return evh;
}else {
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.comment_row, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
Log.e("Adapter", "onBindViewHolder Called");
if(viewHolder instanceof ViewHolder) {
ViewHolder holder = (ViewHolder)viewHolder;
comment c = mItems.get(position);
Log.e("Adapter", "Comment is\n: " + c.toString());
final ViewHolder finalHolder = holder;
ImageRequest request = new ImageRequest(c.author_img_link, new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {
if (bitmap != null) {
finalHolder.mThumbnail.setImageBitmap(bitmap);
}
}
}, 0, 0, null,
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
VolleyLog.e("ImageLoader", volleyError.getMessage());
VolleyLog.e("ImageLoader", volleyError.getStackTrace());
}
});
GetVideoInfo.getInstance(mContext.getApplicationContext()).addToRequestQueue(request);
holder.mAuthorName.setText(c.author_name);
holder.mMessage.setText(c.Message);
holder.mMessage.setTypeface(mTf);
holder.mAuthorName.setTypeface(mTf);
}
}
@Override
public int getItemCount() {
Log.e("Adapter", "getItemCount() Called");
return (mItems.size() > 0 ? mItems.size() : 1);
}
@Override
public int getItemViewType(int position) {
Log.e("Adapter", "getItemViewType() Called");
if (mItems.size() == 0) {
return EMPTY_VIEW;
}
return super.getItemViewType(position);
}}
我将使用 public void add(comment item, int position){...}
在 RecyclerView 中添加项目。
在片段中:
private RecyclerView mRecyclerView;
private CommentListAdapter mAdapter;
private LayoutManager mLayoutManager;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_detail, container, false);
....
mLayoutManager = new LinearLayoutManager(getActivity());
mAdapter = new CommentListAdapter(getActivity(),new ArrayList<comment>());
mRecyclerView = (RecyclerView)rootView.findViewById(R.id.comment_list);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
makeJsonObjectRequest(mItem.url);
return rootView;
}
XML 个文件:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/scrollView"
android:background="@android:color/white"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true">
....
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
.....
<android.support.v7.widget.RecyclerView
android:id="@+id/comment_list"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
....
</RelativeLayout>
....
</ScrollView>
comment_row xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="horizontal"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:gravity="right"
android:background="@android:color/darker_gray">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/author_name"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/author_avatar"
android:layout_toStartOf="@+id/author_avatar"
android:gravity="right" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/message"
android:layout_below="@+id/author_name"
android:layout_toLeftOf="@+id/author_avatar"
android:layout_toStartOf="@+id/author_avatar"
android:gravity="right" />
</LinearLayout>
<com.android.volley.toolbox.NetworkImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/author_avatar"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:minHeight="150dp"
android:minWidth="150dp" /></LinearLayout>
我将使用此代码将项目添加到 RecyclerView :
JsonObjectRequest jsonObjReqComment = new
JsonObjectRequest(Request.Method.GET,urlJsonObj+"#comment", null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONArray res = response.getJSONArray("response");
//Log.e("Comment","Count:"+response.toString());
//Log.e("Comment","Count:"+res.length());
for (int i = 0; i < res.length(); i++) {
JSONObject thread = res.getJSONObject(i);
JSONObject author_json = thread.getJSONObject("author");
int dislikes = thread.getInt("dislikes");
int likes = thread.getInt("likes");
String Message = thread.getString("message");
//get Author info
String author_img_link = author_json.getJSONObject("avatar").getString("permalink");
String author_name = author_json.getString("name");
comment c = new comment(dislikes,likes,Message,author_img_link,author_name);
//Log.e("Comment",c.toString());
//commentsList.add(c);
mAdapter.add(c,0);
}
} catch (JSONException e) {
Log.e("OnResponse","Error JSON");
e.printStackTrace();
} catch (Exception e){
Log.e("OnResponse","Error Exception");
e.printStackTrace();
}
}
}
, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("vOLLEY", "Error: " + error.getMessage());
// hide the progress dialog
}
}
){
@Override
public Map<String, String> getHeaders(){
Map<String, String> headers = new HashMap<String, String>();
headers.put("User-agent", "Comment");
return headers;
}
};
由于@yigit 猜测 ScrollView
、RelativeLayout
的组合导致了这个问题,
为 RecyclerView
.
If RecyclerView gets put into a ScrollView, then during measure step its height is unspecified (because ScrollView allows any height) and gets equal to minimum height (as per implementation) which is apparently zero.
参考:android: RecyclerView inside a ScrollView
解决方案: - 将视图放在 RecyclerView 的行中 - 计算列表项的大小并以编程方式设置 ListView 的高度 http://vardhan-justlikethat.blogspot.com/2014/04/android-listview-inside-scrollview.html
除了@SanatiSharif 和@sohrab 的回答,您还必须执行以下强制步骤。
请务必调用 setLayoutManager
,如下所示。
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
在将adapter设置到recyclerView之前,否则无法正常工作。 如果需要,您可以自定义它。 this link 将让您了解 LayoutManager 的工作原理。
来晚了,希望对大家有所帮助。尝试以下任一方法:
第一个解决方案: 确保你没有不必要地使用这一行
recyclerView.setHasFixedSize(true);
第二种解决方案:
确保将布局管理器设置为 recyclerView
recycler.setLayoutManager(new LinearLayoutManager(this));
第三种方案:
你 getItemCount
returns 0,所以 RecyclerView
从不尝试实例化视图。使其 return 大于 0
在我的例子中,我有这个结构
<ScrollView>
<RelativeLayout>
<android.support.v7.widget.RecyclerView/>
</RelativeLayout>
</ScrollView>
我解决了删除 Relative 的问题
<ScrollView>
<android.support.v7.widget.RecyclerView/>
</ScrollView>
可能情况不同,但对我来说,我只是忘记按如下方式设置布局管理器:
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recycler.setLayoutManager(layoutManager);
希望对您有所帮助:)
在我的案例中,我使用的是 Fragment-> ViewPager 和 Tablayout -> Inside viewpagers item 我使用的是 RecyclerView。
所以我没有调用 ViewPagerAdapter(getChildFragmentManager()) ,而是调用了 ViewPagerAdapter(getSupportFragmentManager()) ,这就是为什么我的任何回收器适配器项目都没有被调用的原因。
因此在片段中设置 ViewPagerAdapter 的正确方法是
ViewPagerAdapter(getChildFragmentManager())
有点傻,但另一个可以阻止对方法的调用的是将视图的可见性声明为 GONE。
android:visibility="gone"
recyclerView.setVisibility(View.GONE);
其中任何一个都会阻止 RecyclerView.Adapter
中方法的调用希望对大家有所帮助。
我遇到了类似的问题,但上述 none 个答案对我有所帮助。
最后,我发现我在为我的 RecyclerView 所在的 Fragment 创建和绑定视图时犯了一个错误:
有问题的代码
FormPageFragment.onCreate
binding=FormPageBinding.inflate(layoutInflater)
但在 onCreateView 中我这样做了:
FormPageFragment.onCreate查看
return inflater.inflate(R.layout.form_page, container, false)
之后在 onStart 中像这样设置适配器:
FormPageFragment.onStart
binding.formContent.adapter=FormEntriesAdapter(page, viewModel.enteredData)
解决方案
但这是垃圾。它应该在 onCreateView 中完成,当然 binding.rootView 需要作为视图 返回,否则绑定视图不会附加到布局并设置任何适配器它们没有效果。
onCreateView 的工作版本
binding=FormPageBinding.inflate(layoutInflater)
return binding.root
因此,与 RecyclerView 本身相比,片段实例化、创建和绑定正确视图的问题更多。