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(数组列表)