无法查看 RecyclerView 中的条目
Unable to view entries in a RecyclerView
我目前正在使用 RecyclerView 在水平方向的列表中显示一组带有文本的图像。问题是在设置适配器并通知它数据更改后,我没有看到正在填充的网格。我以前使用 gridView 和 arrayAdapter 没有任何问题。我错过了一些基本的东西吗?
** 另外,我检查了 logcat 但没有发现任何异常。但是,如果您需要查看它,请告诉我,我会在此处添加它 **
我按以下方式设置了我的数据和适配器:
模型:CastViewObject
public class CastViewObject {
String castImageUrl;
String castName;
String castCharName;
public CastViewObject(String castName, String castCharName, String castImageUrl) {
this.castImageUrl = castImageUrl;
this.castName = castName;
this.castCharName = castCharName;
}
public String getCastImageUrl() {
return castImageUrl;
}
public void setCastImageUrl(String castImageUrl) {
this.castImageUrl = castImageUrl;
}
public String getCastCharName() {
return castCharName;
}
public void setCastCharName(String castCharName) {
this.castCharName = castCharName;
}
public String getCastName() {
return castName;
}
public void setCastName(String castName) {
this.castName = castName;
}
}
适配器:CastViewAdapter(扩展 RecyclerView.Adapter)- 目前仅显示覆盖的方法。
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public TextView textView;
public ViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.cast_image);
textView = (TextView) itemView.findViewById(R.id.cast_name);
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
mContext = parent.getContext();
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View castView = layoutInflater.inflate(R.layout.cast_item_layout,parent,false);
ViewHolder viewHolder = new ViewHolder(castView);
return viewHolder;
}
@Override
public void onBindViewHolder(CastViewAdapter.ViewHolder holder, int position) {
final String LOG_TAG = getClass().getSimpleName();
CastViewObject castObject = castViewList.get(position);
TextView textView = holder.textView;
textView.setText(castObject.getCastName());
Picasso
.with(mContext)
.load(castViewList.get(position).getCastImageUrl())
.resize(500, 750)
.error(R.drawable.user_placeholder_image)
.into(holder.imageView, new Callback() {
@Override
public void onSuccess() {
count++;
}
@Override
public void onError() {
Log.e(LOG_TAG, "Error in loading images");
}
});
}
@Override
public int getItemCount() {
return castViewList.size();
}
自定义行:cast_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/cast_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
<TextView
android:id="@+id/cast_name"
android:layout_alignParentBottom="true"
android:background="@color/title_background_color"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|bottom"
android:textColor="@color/title_text_color"/>
</LinearLayout>
片段布局中的 RecyclerView:
<android.support.v7.widget.RecyclerView
android:id="@+id/cast_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignLeft="@+id/movie_image_detail"
android:layout_alignStart="@+id/movie_image_detail"
android:layout_below="@+id/cast_divider"
android:layout_marginTop="10dp"
android:clickable="false" />
以下是我在 onCreateView
方法中设置适配器的方法:
RecyclerView recyclerView = (RecyclerView)view.findViewById(R.id.cast_list_view);
castAdapter = new CastViewAdapter(new ArrayList<CastViewObject>());
recyclerView.setAdapter(castAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(linearLayoutManager);
requestMovieDetails();
..并通知适配器数据的变化:
public void setCastView(List<CastViewObject> castViewList){
castAdapter.setCastViewList(castViewList);
castAdapter.notifyDataSetChanged();
}
你必须在这行之后 setAdapter
:
recyclerView.setLayoutManager(linearLayoutManager);
更新:
您刚刚将新对象分配给 this.castViewList
,但您的适配器绑定到空的旧对象,因此 RecyclerView
中没有任何内容可显示。
你必须这样做:
this.castViewList.clear();
this.castViewList.addAll(castViewList);
正如一些人已经建议的那样,确保在将适配器附加到 recyclerview 之前为视图分配布局。否则,您的视图很可能是空白的。
看看documentation中的例子:
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// specify an adapter (see also next example)
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
将 LinearLayout
宽度、高度更改为 wrap_content
,并将 ImageView
、TextView
和高度设置为特定数字。
// ---> ver3.
public class TestAdapter extends RecyclerView.Adapter<TestAdapter>.ViewHolder> {
// -----------> c).
private ArrayList<ModelObject> personArray;
private Context context;
// -----------> d). Set up a custom adapter constructor to pass data into this adapter
public TestAdapter(ArrayList<ModelObject> data, Context context) {
// And link the constructor's params with your adapter's member vars.
this.context = context; // I use this context for any UI feedback (say a Toast'er':))
this.personArray = data;
}
@Override
public SpecAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// -----------> b). create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_spec_view, parent, false); // This is where you actually should call your context from parent
// because the context is for each view (row) and the parent here
// is the ViewGroup parent (parameter) not for the whole adapter
ViewHolder vh = new ViewHolder(v); // Instantiate a viewholder from a view and return it
return vh; // This process happens over and over again for each
// row.
}
@Override
public void onBindViewHolder(SpecAdapter.ViewHolder holder, int position) {
/* onBindViewHolder is used to inject data into your objects (TextViews, Buttons, etc.) */
// ------------> e).
holder.userName.setText(personArray.get(position).getUserName()); // getUserName() is a getter from your model object you store on the data array
holder.userIcon.setImageResource(R.drawable.spec_icon); // Say you have a class Person, this class needs a setUserName and a getUserName
// also, <personArray> is what your data_feeder would be (what I was asking
// earlier on SO). You have to pass to the adapter this List or Array from your HTTP
// method.
}
@Override
public int getItemCount() {
return 0;
}
// ----------> a). Custom ViewHolder
public class ViewHolder extends RecyclerView.ViewHolder {
TextView userName; // you can add any type of objects you'd like to work with
ImageView userIcon; // at a row level
public ViewHolder(View v) {
super(v);
// adjust your resource name to fit your own row's widgets
userName = (TextView)itemView.findViewById(R.id.row_textview);
specIcon = (ImageView)itemView.findViewById(R.id.row_spec_icon);
v.setClickable(true);
}
}
}
我目前正在使用 RecyclerView 在水平方向的列表中显示一组带有文本的图像。问题是在设置适配器并通知它数据更改后,我没有看到正在填充的网格。我以前使用 gridView 和 arrayAdapter 没有任何问题。我错过了一些基本的东西吗?
** 另外,我检查了 logcat 但没有发现任何异常。但是,如果您需要查看它,请告诉我,我会在此处添加它 **
我按以下方式设置了我的数据和适配器:
模型:CastViewObject
public class CastViewObject {
String castImageUrl;
String castName;
String castCharName;
public CastViewObject(String castName, String castCharName, String castImageUrl) {
this.castImageUrl = castImageUrl;
this.castName = castName;
this.castCharName = castCharName;
}
public String getCastImageUrl() {
return castImageUrl;
}
public void setCastImageUrl(String castImageUrl) {
this.castImageUrl = castImageUrl;
}
public String getCastCharName() {
return castCharName;
}
public void setCastCharName(String castCharName) {
this.castCharName = castCharName;
}
public String getCastName() {
return castName;
}
public void setCastName(String castName) {
this.castName = castName;
}
}
适配器:CastViewAdapter(扩展 RecyclerView.Adapter)- 目前仅显示覆盖的方法。
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public TextView textView;
public ViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.cast_image);
textView = (TextView) itemView.findViewById(R.id.cast_name);
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
mContext = parent.getContext();
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View castView = layoutInflater.inflate(R.layout.cast_item_layout,parent,false);
ViewHolder viewHolder = new ViewHolder(castView);
return viewHolder;
}
@Override
public void onBindViewHolder(CastViewAdapter.ViewHolder holder, int position) {
final String LOG_TAG = getClass().getSimpleName();
CastViewObject castObject = castViewList.get(position);
TextView textView = holder.textView;
textView.setText(castObject.getCastName());
Picasso
.with(mContext)
.load(castViewList.get(position).getCastImageUrl())
.resize(500, 750)
.error(R.drawable.user_placeholder_image)
.into(holder.imageView, new Callback() {
@Override
public void onSuccess() {
count++;
}
@Override
public void onError() {
Log.e(LOG_TAG, "Error in loading images");
}
});
}
@Override
public int getItemCount() {
return castViewList.size();
}
自定义行:cast_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/cast_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
<TextView
android:id="@+id/cast_name"
android:layout_alignParentBottom="true"
android:background="@color/title_background_color"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|bottom"
android:textColor="@color/title_text_color"/>
</LinearLayout>
片段布局中的 RecyclerView:
<android.support.v7.widget.RecyclerView
android:id="@+id/cast_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignLeft="@+id/movie_image_detail"
android:layout_alignStart="@+id/movie_image_detail"
android:layout_below="@+id/cast_divider"
android:layout_marginTop="10dp"
android:clickable="false" />
以下是我在 onCreateView
方法中设置适配器的方法:
RecyclerView recyclerView = (RecyclerView)view.findViewById(R.id.cast_list_view);
castAdapter = new CastViewAdapter(new ArrayList<CastViewObject>());
recyclerView.setAdapter(castAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(linearLayoutManager);
requestMovieDetails();
..并通知适配器数据的变化:
public void setCastView(List<CastViewObject> castViewList){
castAdapter.setCastViewList(castViewList);
castAdapter.notifyDataSetChanged();
}
你必须在这行之后 setAdapter
:
recyclerView.setLayoutManager(linearLayoutManager);
更新:
您刚刚将新对象分配给 this.castViewList
,但您的适配器绑定到空的旧对象,因此 RecyclerView
中没有任何内容可显示。
你必须这样做:
this.castViewList.clear();
this.castViewList.addAll(castViewList);
正如一些人已经建议的那样,确保在将适配器附加到 recyclerview 之前为视图分配布局。否则,您的视图很可能是空白的。
看看documentation中的例子:
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// specify an adapter (see also next example)
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
将 LinearLayout
宽度、高度更改为 wrap_content
,并将 ImageView
、TextView
和高度设置为特定数字。
// ---> ver3.
public class TestAdapter extends RecyclerView.Adapter<TestAdapter>.ViewHolder> {
// -----------> c).
private ArrayList<ModelObject> personArray;
private Context context;
// -----------> d). Set up a custom adapter constructor to pass data into this adapter
public TestAdapter(ArrayList<ModelObject> data, Context context) {
// And link the constructor's params with your adapter's member vars.
this.context = context; // I use this context for any UI feedback (say a Toast'er':))
this.personArray = data;
}
@Override
public SpecAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// -----------> b). create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_spec_view, parent, false); // This is where you actually should call your context from parent
// because the context is for each view (row) and the parent here
// is the ViewGroup parent (parameter) not for the whole adapter
ViewHolder vh = new ViewHolder(v); // Instantiate a viewholder from a view and return it
return vh; // This process happens over and over again for each
// row.
}
@Override
public void onBindViewHolder(SpecAdapter.ViewHolder holder, int position) {
/* onBindViewHolder is used to inject data into your objects (TextViews, Buttons, etc.) */
// ------------> e).
holder.userName.setText(personArray.get(position).getUserName()); // getUserName() is a getter from your model object you store on the data array
holder.userIcon.setImageResource(R.drawable.spec_icon); // Say you have a class Person, this class needs a setUserName and a getUserName
// also, <personArray> is what your data_feeder would be (what I was asking
// earlier on SO). You have to pass to the adapter this List or Array from your HTTP
// method.
}
@Override
public int getItemCount() {
return 0;
}
// ----------> a). Custom ViewHolder
public class ViewHolder extends RecyclerView.ViewHolder {
TextView userName; // you can add any type of objects you'd like to work with
ImageView userIcon; // at a row level
public ViewHolder(View v) {
super(v);
// adjust your resource name to fit your own row's widgets
userName = (TextView)itemView.findViewById(R.id.row_textview);
specIcon = (ImageView)itemView.findViewById(R.id.row_spec_icon);
v.setClickable(true);
}
}
}