PagerAdapter 内的 RecyclerView 不更新内容
RecyclerView inside PagerAdapter not updating content
我已经搜索并尝试了很多来让它工作,但我就是无法让它工作...
我有一个 PagerAdapter
片段。每个页面都有一个 RecyclerView
和一个视图列表。
当我点击 RecyclerView
中的其中一项时,ImageView
应该是 shown/hidden(星号会显示 - 收藏夹)。
一切正常,但只有当我单击其中一项时,离开片段,然后再次输入 PagerAdapter
片段。
这是我的 PagerAdapter
代码:
private ArrayList<List<String[]>> schedule;
private Context context;
private LayoutInflater layoutInflater;
private RecyclerView recyclerView;
private ArtistAdapter adapter;
//Fill schedule with information in constructor
...
@Override
public Object instantiateItem(ViewGroup container, final int position) {
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View item_view = layoutInflater.inflate(R.layout.schema_page, container, false);
adapter = new ArtistAdapter(context, getData(backgrounds, schedule.get(position)));
recyclerView = (RecyclerView) item_view.findViewById(R.id.artist_list);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(adapter);
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, recyclerView ,new RecyclerItemClickListener.OnItemClickListener() {
@Override public void onItemClick(View view, int itemPosition) {
toggleFavorite(itemPosition, position);
}
})
);
container.addView(item_view);
return item_view;
}
private void toggleFavorite(int itemPosition, int day){
String[] artist = schedule.get(day).get(itemPosition);
if (artist[5].equals("false")){
artist[5] = "true";
} else {
artist[5] = "false"; //Yes, I need it this way.
}
adapter.swap(getData(backgrounds, schedule.get(day), star));
//Do other things that have to be done in the PagerAdapter
}
我的适配器代码:
class ArtistAdapter extends RecyclerView.Adapter<ArtistAdapter.ArtistViewHolder>{
private LayoutInflater inflater;
private List<ArtistRow> data = Collections.emptyList();
ArtistAdapter (Context context, List<ArtistRow> data){
inflater = LayoutInflater.from(context);
this.data = data;
}
@Override
public ArtistViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.artist_row, parent, false);
return new ArtistViewHolder(view);
}
@Override
public void onBindViewHolder(ArtistViewHolder holder, int position) {
ArtistRow current = data.get(position);
holder.name.setText(current.name.toUpperCase());
holder.type.setText(current.type.toUpperCase());
holder.time.setText(current.time.toUpperCase());
holder.place.setText(current.place.toUpperCase());
holder.background.setImageBitmap(current.background);
holder.star.setImageBitmap(current.star);
if (current.starShow.equals("true")){
holder.star.setVisibility(View.VISIBLE);
} else {
holder.star.setVisibility(View.INVISIBLE);
}
}
public void swap(List<ArtistRow> artists){
data.clear();
data.addAll(artists);
notifyDataSetChanged();
}
@Override
public int getItemCount() {
return data.size();
}
class ArtistViewHolder extends RecyclerView.ViewHolder {
ImageView background;
ImageView star;
TextView name;
TextView type;
TextView time;
TextView place;
ArtistViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.artist_name);
type = (TextView) itemView.findViewById(R.id.artist_type);
time = (TextView) itemView.findViewById(R.id.artist_time);
place = (TextView) itemView.findViewById(R.id.artist_place);
background= (ImageView) itemView.findViewById(R.id.artist_bg);
star = (ImageView) itemView.findViewById(R.id.star);
}
}
}
我认为适配器有问题。
instantiateItem
在预加载第二个页面时被第二次调用。所以我用第一页的内容换掉了第二页,而不是替换第一页,因为它换掉了最后一个实例化的项目。
当我点击第一页上的一个项目然后滑动到下一个时,下一个是第一页的副本(但是我点击的项目上有一个星号,这就是我想要的第一页页)而不显示第二页。
因此,如果我滚动页面并且最后 instantiateItem
页是我当前正在查看的页面,则交换工作正常。
无论如何,我该如何解决这个问题?
提前致谢!
我不是很确定,我也没有测试过你的代码,但我以前遇到过同样的事情。
你能在你的适配器构造函数中试试这个吗
private List<ArtistRow> data;
ArtistAdapter (Context context, List<ArtistRow> data){
inflater = LayoutInflater.from(context);
this.data = new ArrayList<>();
this.data.addAll(data);
}
好的,所以我解决了这个问题!
我没有在 instantiateItem
方法中覆盖适配器,而是创建了一个带有适配器的数组,如下所示:
private ArtistAdapter[] adapters;
// Instantiate the array in my constructor
@Override
public Object instantiateItem(ViewGroup container, final int position) {
...
adapters[position] = new ArtistAdapter(context, getData(backgrounds, schedule.get(position)));
...
recyclerView.setAdapter(adapters[position]);
}
交换:
adapters[day].swap(getData(backgrounds, schedule.get(day), star));
我也认为添加这个也是一个想法:
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
...
adapters[position] = null;
}
如有错误或遗漏请指正!
谢谢!
你可以试试:
recyclerview.setAdapter(adapter);
recyclerview.scrollToPosition(position);
或者像这样在你的适配器中创建方法
public void setData(ArrayList<Quote> arrayList) {
this.arrayList.clear();
this.arrayList.addAll(arrayList);
notifyDataSetChanged();
}
并在您的 activity 片段中使用
adapter.setData(数组列表)
我已经搜索并尝试了很多来让它工作,但我就是无法让它工作...
我有一个 PagerAdapter
片段。每个页面都有一个 RecyclerView
和一个视图列表。
当我点击 RecyclerView
中的其中一项时,ImageView
应该是 shown/hidden(星号会显示 - 收藏夹)。
一切正常,但只有当我单击其中一项时,离开片段,然后再次输入 PagerAdapter
片段。
这是我的 PagerAdapter
代码:
private ArrayList<List<String[]>> schedule;
private Context context;
private LayoutInflater layoutInflater;
private RecyclerView recyclerView;
private ArtistAdapter adapter;
//Fill schedule with information in constructor
...
@Override
public Object instantiateItem(ViewGroup container, final int position) {
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View item_view = layoutInflater.inflate(R.layout.schema_page, container, false);
adapter = new ArtistAdapter(context, getData(backgrounds, schedule.get(position)));
recyclerView = (RecyclerView) item_view.findViewById(R.id.artist_list);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(adapter);
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, recyclerView ,new RecyclerItemClickListener.OnItemClickListener() {
@Override public void onItemClick(View view, int itemPosition) {
toggleFavorite(itemPosition, position);
}
})
);
container.addView(item_view);
return item_view;
}
private void toggleFavorite(int itemPosition, int day){
String[] artist = schedule.get(day).get(itemPosition);
if (artist[5].equals("false")){
artist[5] = "true";
} else {
artist[5] = "false"; //Yes, I need it this way.
}
adapter.swap(getData(backgrounds, schedule.get(day), star));
//Do other things that have to be done in the PagerAdapter
}
我的适配器代码:
class ArtistAdapter extends RecyclerView.Adapter<ArtistAdapter.ArtistViewHolder>{
private LayoutInflater inflater;
private List<ArtistRow> data = Collections.emptyList();
ArtistAdapter (Context context, List<ArtistRow> data){
inflater = LayoutInflater.from(context);
this.data = data;
}
@Override
public ArtistViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.artist_row, parent, false);
return new ArtistViewHolder(view);
}
@Override
public void onBindViewHolder(ArtistViewHolder holder, int position) {
ArtistRow current = data.get(position);
holder.name.setText(current.name.toUpperCase());
holder.type.setText(current.type.toUpperCase());
holder.time.setText(current.time.toUpperCase());
holder.place.setText(current.place.toUpperCase());
holder.background.setImageBitmap(current.background);
holder.star.setImageBitmap(current.star);
if (current.starShow.equals("true")){
holder.star.setVisibility(View.VISIBLE);
} else {
holder.star.setVisibility(View.INVISIBLE);
}
}
public void swap(List<ArtistRow> artists){
data.clear();
data.addAll(artists);
notifyDataSetChanged();
}
@Override
public int getItemCount() {
return data.size();
}
class ArtistViewHolder extends RecyclerView.ViewHolder {
ImageView background;
ImageView star;
TextView name;
TextView type;
TextView time;
TextView place;
ArtistViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.artist_name);
type = (TextView) itemView.findViewById(R.id.artist_type);
time = (TextView) itemView.findViewById(R.id.artist_time);
place = (TextView) itemView.findViewById(R.id.artist_place);
background= (ImageView) itemView.findViewById(R.id.artist_bg);
star = (ImageView) itemView.findViewById(R.id.star);
}
}
}
我认为适配器有问题。
instantiateItem
在预加载第二个页面时被第二次调用。所以我用第一页的内容换掉了第二页,而不是替换第一页,因为它换掉了最后一个实例化的项目。
当我点击第一页上的一个项目然后滑动到下一个时,下一个是第一页的副本(但是我点击的项目上有一个星号,这就是我想要的第一页页)而不显示第二页。
因此,如果我滚动页面并且最后 instantiateItem
页是我当前正在查看的页面,则交换工作正常。
无论如何,我该如何解决这个问题?
提前致谢!
我不是很确定,我也没有测试过你的代码,但我以前遇到过同样的事情。
你能在你的适配器构造函数中试试这个吗
private List<ArtistRow> data;
ArtistAdapter (Context context, List<ArtistRow> data){
inflater = LayoutInflater.from(context);
this.data = new ArrayList<>();
this.data.addAll(data);
}
好的,所以我解决了这个问题!
我没有在 instantiateItem
方法中覆盖适配器,而是创建了一个带有适配器的数组,如下所示:
private ArtistAdapter[] adapters;
// Instantiate the array in my constructor
@Override
public Object instantiateItem(ViewGroup container, final int position) {
...
adapters[position] = new ArtistAdapter(context, getData(backgrounds, schedule.get(position)));
...
recyclerView.setAdapter(adapters[position]);
}
交换:
adapters[day].swap(getData(backgrounds, schedule.get(day), star));
我也认为添加这个也是一个想法:
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
...
adapters[position] = null;
}
如有错误或遗漏请指正!
谢谢!
你可以试试:
recyclerview.setAdapter(adapter);
recyclerview.scrollToPosition(position);
或者像这样在你的适配器中创建方法
public void setData(ArrayList<Quote> arrayList) {
this.arrayList.clear();
this.arrayList.addAll(arrayList);
notifyDataSetChanged();
}
并在您的 activity 片段中使用
adapter.setData(数组列表)