notify *方法不会更新RecyclerView的视图

时间:2017-11-03 21:55:51

标签: android android-recyclerview notifydatasetchanged

我有一个管理联系人的应用程序,我使用2 RecyclerView来显示未选择和选定的联系人。用户可以选择和取消选择联系人。

这是我的情景:

我有两个RecyclerView,一个用于管理选定的联系人,另一个用于管理未选择的联系人。当用户从未选择的列表中选择联系人时,该联系人将从该列表中删除该联系人并将其插入所选列表中。如果用户从所选列表中选择联系人,只会从所选列表中删除联系人并将其插入未选择列表中,则会发生同样的情况。我已经实施了自定义RadioButton,并且在onCheckedChanged事件中,我在选择或取消选择时从适当的适配器中删除联系人。

我有一个适用于所选列表的适配器(SelectedContactsAdapter),另一个适用于未选择的列表(UnselectedContactsAdapter)。我使用新的SortedList集合来管理适配器的数据,并在SortedList的回调中通知适配器更改并发送回调消息以更新其他适配器。
< BR />

例如,如果用户在未选择的列表中选择一个联系人,则在onCheckedChanged事件中我保存联系人,然后将其从适配器中删除(我这样做是因为我需要将其传递给回调,因此它可以插入另一个适配器),然后我从适配器中删除该联系人。这会触发onRemoved的{​​{1}}方法,并在那里调用SortedListnotifyItemRemoved(position)将被删除的联系人的位置保留)以及在所选内容中插入该联系人的回调列表。

由于某种原因,notify *方法不会更新position视图。我尝试使用RecyclerView并且它有效,但它不适合我,因为我需要快速,几乎是即时的更新。

我使用notifyDataSetChanged为FastScroll启动了2 RecyclerView。以防重要......

这是我的代码:

setNestedScrollingEnabled(false)


public abstract class FilterableContactsAdapter extends RecyclerView.Adapter<FilterableContactsAdapter.ContactViewHolder>
        implements Filterable {

    //... Some variables like the filter
    protected Contact mLastContactTouched;
    protected SortedList<Contact> mFilteredContacts;
    protected ContactCallback mContactCallback;
    protected boolean mPropagate;

    public FilterableContactsAdapter() {
        mPropagate = true;
        mFilteredContacts = new SortedList<>(Contact.class, new SortedList.Callback<Contact>() {
            @Override
            public int compare(Contact o1, Contact o2) {
                return o1.getName().compareToIgnoreCase(o2.getName());
            }

            @Override
            public void onChanged(int position, int count) {
                notifyItemChanged(position);
                if(mContactCallback != null && mPropagate) mContactCallback.onContactChanged(mLastContactTouched, position);
            }

            @Override
            public boolean areContentsTheSame(Contact oldItem, Contact newItem) {
                boolean sameIds = (oldItem.getId() == newItem.getId());
                boolean sameNames = oldItem.getName().equals(newItem.getName());
                boolean samePhoneNumbers = oldItem.getNormalizedPhoneNumber().equals(newItem.getNormalizedPhoneNumber());

                if(sameIds && sameNames && samePhoneNumbers) return true;
                else return false;
            }

            @Override
            public boolean areItemsTheSame(Contact item1, Contact item2) {
                return item1.getId() == item2.getId();
            }

            @Override
            public void onInserted(int position, int count) {
                notifyItemInserted(position);
                /*if(FilterableContactsAdapter.this instanceof SelectedContactsAdapter) notifyDataSetChanged();
                else notifyItemInserted(position);*/
                if(mContactCallback != null && mPropagate) mContactCallback.onContactInserted(mLastContactTouched, position);
            }

            @Override
            public void onRemoved(int position, int count) {
                notifyItemRemoved(position);
                /*if(FilterableContactsAdapter.this instanceof SelectedContactsAdapter) notifyDataSetChanged();
                else notifyItemRemoved(position);*/
                if(mContactCallback != null && mPropagate) mContactCallback.onContactRemoved(mLastContactTouched, position);
            }

            @Override
            public void onMoved(int fromPosition, int toPosition) {
                notifyItemMoved(fromPosition, toPosition);
                if(mContactCallback != null && mPropagate) mContactCallback.onContactMoved(mLastContactTouched, fromPosition, toPosition);
            }
        });
    }

    public void add(Contact contact) {
        mFilteredContacts.add(contact);
    }

    public void remove(Contact contact) {
        mFilteredContacts.remove(contact);
    }

    //... Some other methods like onCreateViewHolder, the ContactViewHolder declaration and the filter implementation
}


public interface ContactCallback {
    void onContactInserted(Contact contact, int adapterPosition);
    void onContactRemoved(Contact contact, int adapterPosition);
    void onContactMoved(Contact contact, int from, int to);
    void onContactChanged(Contact contact, int adapterPosition);
}


public class SelectedContactsAdapter extends FilterableContactsAdapter {

    @Override
    public void onBindViewHolder(final ContactViewHolder holder, final int position) {
        final Contact contact = mFilteredContacts.get(position);

        if(contact != null) {
            holder.parentLayout.setVisibility(View.VISIBLE);
            holder.nameTV.setText(contact.getName());
            holder.phoneNumberTV.setText(contact.getNormalizedPhoneNumber());
            holder.selectCB.setSafeCheck(true, SafeCheckBox.IGNORE);
            holder.selectCB.setOnSafeCheckedListener(new SafeCheckBox.OnSafeCheckedListener() {
                @Override
                public void onAlwaysCalledListener(CompoundButton buttonView, boolean isChecked) {

                }

                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    contact.setSelected(isChecked);
                    mLastContactTouched = contact;
                    remove(contact);
                }
            });
        } else {
            holder.parentLayout.setVisibility(View.GONE);
        }
    }
}


public class UnselectedContactsAdapter extends FilterableContactsAdapter {

    @Override
    public void onBindViewHolder(final ContactViewHolder holder, final int position) {
        final Contact contact = mFilteredContacts.get(position);

        if(!contact.isSelected()) {
            holder.parentLayout.setVisibility(View.VISIBLE);
            holder.nameTV.setText(contact.getName());
            holder.phoneNumberTV.setText(contact.getNormalizedPhoneNumber());
            holder.selectCB.setSafeCheck(false, SafeCheckBox.IGNORE);
            holder.selectCB.setOnSafeCheckedListener(new SafeCheckBox.OnSafeCheckedListener() {
                @Override
                public void onAlwaysCalledListener(CompoundButton buttonView, boolean isChecked) {

                }

                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    contact.setSelected(isChecked);
                    mLastContactTouched = contact;
                    remove(contact);
                }
            });
        } else {
            holder.parentLayout.setVisibility(View.GONE);
        }
    }
}


以下是我正在谈论的一些照片:

我在这里选择了一个联系人:
one_contact_selected_top one_contact_selected_bottom


我在这里选择了两个联系人(“Abuela”和“Adela Zapata”):
two_contacts_selected_top two_contacts_selected_bottom


在这里,在左边,我取消选择了我选择的第一个项目(联系人“Abuela”)。右侧是未选中所有联系人的列表:
first_contact_unselected unselected_list

1 个答案:

答案 0 :(得分:0)

好吧,经过一周的研究后,我找到了解决方案......我非常怀疑setHasFixedSize(true)与视图有关,即使项目已更新,也不会调整大小或重新绘制..从2个适配器配置中删除该行后,所有工作都非常顺利......有趣的是,我发布的解决方案比我发布问题的时间晚了几个。