【问题标题】:Android Realm Database not updating RecordAndroid领域数据库不更新记录
【发布时间】:2017-05-23 11:44:44
【问题描述】:

我是 Android 开发新手,我正在尝试对 Recyclerview 中的项目位置进行排序,我正在使用领域数据库,我的适配器数据集是 RealmResults<ShoppingList>

这是我的Adapter 请看看我的moveItemDownupdateItemPosition 方法我试图在updateItemPosition 方法中更新项目位置,但它不起作用。我还在适配器下方附上了我的视图

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {

    private RealmResults<ShoppingList> dataList;
    private Realm mRealm;
    private LayoutInflater mInflater;

    public RecyclerAdapter(Context context, RealmResults<ShoppingList> data, Realm reamDatabaseInstence){
        this.dataList = data;
        this.mInflater = LayoutInflater.from(context);
        mRealm = reamDatabaseInstence;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Log.i("Recycler", "onCreateViewHolder");

        View view = mInflater.inflate(R.layout.shopping_list_item, parent,false);
        MyViewHolder holder = new MyViewHolder(view);
        return holder;
    }

    @Override
    public int getItemCount() {
        return dataList.size();
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Log.i("Recycler", "onBindViewHolder " + position);

        ShoppingList currentItem = dataList.get(position);
        holder.setData(currentItem, position);
        holder.setListener();
    }

    public void moveItemDown(int position){
        if( position == (dataList.size()-1) ) { return; }
        int oi = position;
        int ni = position+1;
        updateItemPosition(oi, ni);
        notifyDataSetChanged();

    }

    public void moveItemUp(int position){
        // Need to implement after down sort work
    }

    private void updateItemPosition(final int pos, final int new_pos){
        mRealm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                ShoppingList old_item = realm.where(ShoppingList.class)
                        .equalTo("position", pos)
                        .findFirst();
                old_item.setPosition(new_pos);
                Log.d("UpdateData: ",old_item.getTitle()+" "+old_item.getPosition());

                ShoppingList new_item = realm.where(ShoppingList.class)
                        .equalTo("position", new_pos)
                        .findFirst();
                new_item.setPosition(pos);
                Log.d("UpdateData: ",new_item.getTitle()+" "+new_item.getPosition());

            }
        });
    }

    class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        TextView title;
        ImageButton up, down;
        ImageView image;
        int position;
        ShoppingList current;

        MyViewHolder(View itemView) {
            super(itemView);
            title = (TextView) itemView.findViewById(R.id.shopping_card_view_title);
            image = (ImageView) itemView.findViewById(R.id.shopping_card_view_image);
            up = (ImageButton) itemView.findViewById(R.id.shopping_card_view_up_btn);
            down = (ImageButton) itemView.findViewById(R.id.shopping_card_view_down_btn);
        }

        void setData(ShoppingList i, int position) {
            title.setText( i.getTitle() );
            image.setImageResource(i.getImageId());
            this.position = position;
            this.current = i;
        }

        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.shopping_card_view_up_btn:
                    moveItemUp(position);
                    break;
                case R.id.shopping_card_view_down_btn:
                    moveItemDown(position);
                    break;
            }
        }

        void setListener() {
            up.setOnClickListener(MyViewHolder.this);
            down.setOnClickListener(MyViewHolder.this);
        }
    }

}

【问题讨论】:

    标签: android android-recyclerview realm


    【解决方案1】:

    迟到的回复会对你有所帮助,这是两个答案的结合 EpicPandaForce 提供了一个很好的例子来使用 RealmRecyclerViewAdapter 并使你的 Recyclerview 自动化。

    第二个选项
    这是为了使用 UNIQUE ID FIELD 来更改列表项。

    这是您的代码中发生的问题
    基本上,当您通过它的位置获得一个项目时,例如position=1; 并且您更新到位置 2 对吗?现在请注意,您有两个具有相同 position = 2 的项目,现在当您尝试使用 position = 2 获取第一个项目时,领域返回您从位置 1 更新到 2 的相同项目现在发生的情况,您将日期位置更新回 position=1 ;

    taman neupane给你一个好主意,但他描述得不多。

    试试这个

    private void updateItemPosition(final int pos, final int new_pos){
    
        final String current_item_id = dataList.get(pos).get_id();
        final String new_item_id = dataList.get(new_pos).get_id();
    
        mRealm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                // Try to find the result with unique id replace this .equalTo("Your Unique ID Field name", current_item_id)
                ShoppingList old_item = realm.where(ShoppingList.class).equalTo("position", pos).findFirst();
    
                old_item.setPosition(new_pos);
                // Also here Try to find the result with unique id replace this .equalTo("Your Unique ID Field name", new_item_id)
                ShoppingList new_item = realm.where(ShoppingList.class).equalTo("position", new_pos).findFirst();
    
                new_item.setPosition(pos);
                //new you can tell you adapter about the changes in dataset.
                notifyItemMoved(pos, new_pos);
                notifyItemRangeChanged(pos, dataList.getSize());
            }
        });
    }
    

    然后用那个更新你的两个函数

    public void moveItemDown(int position){
        if( position == (dataList.size()-1) ) { return; }
        int oi = position;
        int ni = position+1;
        updateItemPosition(oi, ni);
    }
    
    public void moveItemUp(int position){
        if( position == 0 ) { return; }
        int oi = position;
        int ni = position-1;
        updateItemPosition(ni, oi);
    }
    

    就是这样。 如果有人想修改我的解释,我将不胜感激,因为我的英语不好。

    快乐编码。

    【讨论】:

    • 您好,感谢您的解释,让我试试您的解决方案。
    • 完美 :) 非常感谢您的精彩解释和代码。它现在正在工作,
    【解决方案2】:

    要获得自动更新,您应该使用来自https://github.com/realm/realm-android-adaptersRealmRecyclerViewAdapter

    public class RecyclerAdapter extends RealmRecyclerViewAdapter<ShoppingList, RecyclerAdapter.MyViewHolder> { // <-- !
        private Realm mRealm;
        private LayoutInflater mInflater;
    
        public RecyclerAdapter(Context context, RealmResults<ShoppingList> data, Realm realm){
            super(data, true);
            this.mInflater = LayoutInflater.from(context);
            mRealm = realm;
        }
    

    并将dataList 替换为getData()

    【讨论】:

      【解决方案3】:

      我认为您的 ShoppingList 商品对所有人都有唯一的 ID。只需将 id 字段设为主要并使用 realmInsertorUpdate 功能。您无需检查其他任何内容。如果 id 可用,它将更新数据库,如果 id 不可用,它将仅插入。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多