Android在Realm Recyclerview中更改项目运行时的顺序

时间:2016-06-16 09:31:38

标签: realm android-recyclerview

我需要根据字段starredAt

来订购商品列表

我正在使用RealmRecyclerView通过thorbenprimke从Realm DB加载数据到Recyclerview中

该字段会更改用户操作的值,即当用户按下星形按钮时,该项目应移至顶部。

为此,我只是更新对象的starredAt字段。

这些项目已经按starredAt排序,因此领域会加载更新的列表,但它会随机添加一个项目到Recyclerview。

CheatSheet.java

public class CheatSheet extends RealmObject {

@PrimaryKey
private String id;

private RealmList<Item> items;

private String title;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public RealmList<Item> getItems() {
    return items;
}

public void setItems(RealmList<Item> items) {
    this.items = items;
}
}

Item.java

public class Item extends RealmObject {

@PrimaryKey
private String id;

private String description;

private Date starredAt;

public Item() {
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public Date getStarredAt() {
    return starredAt;
}

public void setStarredAt(Date starredAt) {
    this.starredAt = starredAt;
}
}

CheatSheetActivity.java

public class MainActivity extends AppCompatActivity {

RealmRecyclerView revItems;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    setData();
}

private void setData() {
    rvItems = (RealmRecyclerView) findViewById(R.id.rev_items);
    RealmResults<Item> items = Realm.getDefaultInstance().where(CheatSheet.class)
                      .equalTo("id", "some-id").findFirst().getItems()
                      .where()
                      .findAllSorted("starredAt", Sort.DESCENDING);

    ItemRealmListAdapter itemRealmListAdapter = 
                  new ItemRealmListAdapter(this, items, 
                                           true, true);
    rvItems.setAdapter(itemRealmListAdapter);
}

ItemRealmListAdapter.java

public class ItemRealmListAdapter extends RealmBasedRecyclerViewAdapter<Item,
    ItemRealmListAdapter.ItemViewHolder> {

RealmResults<Item> mItems;

public ItemRealmListAdapter(Context context, RealmResults<Item> realmResults,
                            boolean automaticUpdate, boolean animateResults) {
    super(context, realmResults, automaticUpdate, animateResults);
    this.mItems = realmResults;
}

@Override
public ItemViewHolder onCreateRealmViewHolder(ViewGroup viewGroup, int i) {
    return new ItemViewHolder(LayoutInflater.from(viewGroup.getContext())
            .inflate(R.layout.item_layout_cs_text, viewGroup, false));
}

public Item getItem(int position) {
    return mItems.get(position);
}

@Override
public void onBindRealmViewHolder(ItemViewHolder itemViewHolder, int position) {
    itemViewHolder.txtBody.setText(getItem(position).getDescription());
    if (getItem(position).getStarredAt() != null) {
        itemViewHolder.imvStar.setImageResource(R.drawable.ic_star_yellow);
    }
    itemViewHolder.imvStar.setOnClickListener(v -> handleStarClick(v,position));
}

private void handleStarClick(View v, int position) {
    if (getItem(position).getStarredAt() != null) {
        ((ImageView) v).setImageResource(R.drawable.ic_star);
        CheatSheetStorage.unStarItem("some-id", getItem(position));
    } else {
        ((ImageView) v).setImageResource(R.drawable.ic_star_yellow);
        CheatSheetStorage.starItem("some-id", getItem(position));
    }

}

public static class ItemViewHolder extends RealmViewHolder {

    @Bind(R.id.txt_cheat_sheet)
    TextView txtBody;

    @Bind(R.id.img_star)
    ImageView imvStar;


    public ItemViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
    }
}
}

CheatSheetStorage.java

public class CheatSheetStorage {
 public static void unStarItem(String cheatSheetId, Item item) {
    Realm realm = Realm.getDefaultInstance();
    realm.beginTransaction();
    CheatSheet cheatSheet = getCheatSheetById(cheatSheetId);
    Item itemDB = cheatSheet.getItems().where().equalTo("id", item.getId()).findFirst();
    itemDB.setStarredAt(null);
    realm.commitTransaction();
}

public static void starItem(String cheatSheetId, Item item) {
    Realm realm = Realm.getDefaultInstance();
    realm.beginTransaction();
    CheatSheet cheatSheet = getCheatSheetById(cheatSheetId);
    Item itemDB = cheatSheet.getItems().where().equalTo("id", item.getId()).findFirst();
    itemDB.setStarredAt(new Date());
    realm.commitTransaction();
}
}

请参阅以下屏幕截图以获得更清晰的想法:

Screenshot before starring

Screenshot after starring the sixth item

1 个答案:

答案 0 :(得分:1)

@ Rohan-Peshkar - 您必须为适配器提供animateExtraColumnName值。对于动画,适配器会跟踪项目,并且由于该项目的ID不会更改,因此列表不会更新。使用附加列(在您的情况下应该是starredAt列 - 只要它存储为Integer),差异算法将检测更改并更新订单。

供参考:https://github.com/thorbenprimke/realm-recyclerview/blob/2835a543dce20993d8f98a4f773fa0e67132ce52/library/src/main/java/io/realm/RealmBasedRecyclerViewAdapter.java#L177

您还可以查看示例文件夹中的MainActivity。该示例更改了&#34; ABC&#34;中的行的文本。到&#34;更新了ABC&#34;并且列表识别更改,因为主键和引用字段都用于基本上创建复合键以进行区分。