Recyclerview Cursor适配器回收问题

时间:2018-10-18 03:07:41

标签: android android-recyclerview

在我的应用中,用户拥有自己喜欢的电影的列表(recyclerview),对于他喜欢的电影中的每部电影,他都可以添加注释,而在该列表中我遇到了回收问题,当他打开对话框以添加时他在便笺中添加便笺,并且recyclerview中的便笺图标反映了该更改,当添加便笺时,该图标为红色,但是当我单击列表中的另一个项目并返回到刚刚添加了该便笺的项目时注意,“注释”图标变回灰色,并且在对话框中看不到任何注释(注释应为空的textview)。仅当我设法调用FavoriteFragment的OnResume(调用刷新方法)时,该注释才会显示,它调用CursorAdapter changeCursor

点击列表中的一个项目,视图也会展开以显示“添加/编辑笔记”操作,如下所示:

 @Override
public void onBindViewHolder(final FavoriteHolder holder, final int position) {
    // Passing the binding operation to cursor loader
    final boolean isExpanded = position == mExpandedPosition;
    holder.releasesActions.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
    holder.itemView.setActivated(isExpanded);

    if (isExpanded) {
        mPreviousExpandedPosition = position;
    }

    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mExpandedPosition = isExpanded ? -1 : position;
            notifyItemChanged(mPreviousExpandedPosition);
            mCurrentPosition = position;
            holder.initReleaseActions((Cursor) mCursorAdapter.getItem(mCurrentPosition));
            notifyItemChanged(position);
            // fixes recycling issue
            // refresh only last position
            // holder.initReleaseActions();
            // mCursorAdapter.getItem(mPreviousExpandedPosition);
        }
    });

    mCursorAdapter.getCursor().moveToPosition(position);
    mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());
}

initReleaseActions方法应该更新注释操作,以反映注释图标上的更改。

这是它在FavoriteHolder中的实现:

    public void initReleaseActions(Cursor cursor) {
    // Setting our components
    // User saved release actions
    mHeartIcon.setImageResource(R.drawable.ic_favorite_red);

    if (cursor.getInt(cursor.getColumnIndex(DatabaseHelper.COL_NOTE_ADDED)) == 1) {
        mNoteIcon.setImageResource(R.drawable.ic_note_red);
        mNoteText.setText("Edit note");
    }
}

我的问题是为什么这种方法无法发挥作用?我不明白,我认为它应该起作用,如果发生更改,是否总是必须刷新整个光标吗?

哦,这是我对CursorAdapater的实现:

public FavoriteReleasesAdapter(Context context, String sortType, TextView nothingFoundTxt) {
    mContext = context;
    mDatabaseHelper = DatabaseHelper.getDatabaseHelper(mContext);
    mCursor = getUserCursor(sortType);
    mInflater = LayoutInflater.from(mContext);
    mNothingFoundTxt = nothingFoundTxt;
    mAlarmReceiver = new AlarmReceiver();
    mIsCoversHidden = SharedPrefManager.read(SharedPrefManager.KEY_PREF_HIDE_COVERS, false);
    mCursorAdapter = new CursorAdapter(mContext, mCursor, 0) {
        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            View view = mInflater.inflate(R.layout.favorite_release_item, parent, false);
            FavoriteHolder holder = new FavoriteHolder(view);
            holder.setFavoriteReleaseAdapter(FavoriteReleasesAdapter.this);
            holder.setIsCoversHidden(mIsCoversHidden);
            holder.setDatabaseHelper(mDatabaseHelper);
            holder.setAlarmReceiver(mAlarmReceiver);
            holder.setContext(mContext);
            view.setTag(holder);
            return view;
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            FavoriteHolder holder = (FavoriteHolder) view.getTag();
            holder.setFavoriteDetails(cursor);
        }
    };
}
// this is the update method that gets called on FavoriteFragment onResume
public void updateCursor(String sortType) {
    mCursor = getUserCursor(sortType);
    mCursorAdapter.changeCursor(mCursor);
    notifyDataSetChanged();
    toggleEmptyTxt();
    // notifyItemRemoved(mCursor.getPosition());
}

1 个答案:

答案 0 :(得分:0)

  

如果发生更改,是否总是必须刷新整个光标?

是的

游标就像执行查询时数据库的快照。如果更改数据库上的任何内容,则还必须更新游标(运行新查询并用新游标替换旧游标)。如果您不想这样做,可以将光标转换为ArrayList<YourModelClass>,这样就可以动态地更新特定位置。

关于代码的另一点:

if (cursor.getInt(cursor.getColumnIndex(DatabaseHelper.COL_NOTE_ADDED)) == 1) {
    mNoteIcon.setImageResource(R.drawable.ic_note_red);
    mNoteText.setText("Edit note");
}

您仅设置红色图标,而从未设置灰色图标。但是,RecyclerView重用视图。因此,它可能会尝试在电影没有注释的位置(灰色图标)重新使用带有红色图标的视图。因此,正确的方法是:

if (cursor.getInt(cursor.getColumnIndex(DatabaseHelper.COL_NOTE_ADDED)) == 1) {
    mNoteIcon.setImageResource(R.drawable.ic_note_red);
    mNoteText.setText("Edit note");
} else {
    // Re-apply default text and default icon
}