Search code examples
javaandroidandroid-recyclerviewrealmdelete-row

Delete Item from RecyclerView and Realm DB


Image

I have an EditText which adds items to this RecyclerView and to the Realm DB. That works fine. The problem is that I don't know how to remove those items from both the RecyclerView and from the Realm DB. Should this be done on the Fragment or on the adapter? And how? Thanks!

There is an image on top showing a screenshot of the app.

Here is the Fragment where the RecyclerView is:

    public class FragmentMyList extends Fragment{

    private RecyclerView recyclerView;
    private EditText editTxt;
    private FloatingActionButton btn;
    private Item item;
    private ArrayList<Item> itemList;
    private AdapterItemsRecycler adapterItemsRecycler;
    private Realm realm;
    RealmResults<Item> results;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View vistaADevolver = inflater.inflate(R.layout.fragment_my_list, container, false);
        getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        Realm.init(getContext());
        realm = Realm.getDefaultInstance();

        editTxt = (EditText)vistaADevolver.findViewById(R.id.editText);
        btn = (FloatingActionButton) vistaADevolver.findViewById(R.id.button);
        recyclerView = (RecyclerView) vistaADevolver.findViewById(R.id.recyclerViewToDo);

        itemList = new ArrayList<>();
        results = realm.where(Item.class).equalTo("id", 1).findAll();
        final InputMethodManager inputManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);

        adapterItemsRecycler = new AdapterItemsRecycler(results, getActivity(), new ItemsListener());
        recyclerView.setHasFixedSize(true);
        recyclerView.addItemDecoration(new SimpleItemDivider(getActivity()));
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(),LinearLayoutManager.VERTICAL, false));
        recyclerView.setAdapter(adapterItemsRecycler);


        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String itemName = editTxt.getText().toString();
                saveIntoDatabase(itemName);

                inputManager.hideSoftInputFromWindow(getView().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
                editTxt.getText().clear();
                adapterItemsRecycler.notifyDataSetChanged();
            }
        });
        return vistaADevolver;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        realm.close();
    }

    private void saveIntoDatabase(final String itemName) {

        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm bgRealm) {
                item = bgRealm.createObject(Item.class);
                item.setName(itemName);
                item.setPoint(itemName);
                item.setId(1);
                Fragment fragment = new Fragment();
                Bundle bundle = new Bundle();
                bundle.putString("POINT", item.getPoint());
                fragment.setArguments(bundle);
                itemList.add(item);

            }
        }, new Realm.Transaction.OnSuccess() {
            @Override
            public void onSuccess() {
                // Transaction was a success.
                Log.v("database", "Stored ok");
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(Throwable error) {
                // Transaction failed and was automatically canceled.
                Log.e("database", error.getMessage());
            }
        });

    }
    class ItemsListener implements AdapterView.OnClickListener{

        @Override
        public void onClick(View view) {

            Item itemTouched = results.get(recyclerView.getChildAdapterPosition(view));
            EscuchadorInterface unEscuchador = (EscuchadorInterface)getActivity();
            unEscuchador.itemSelected(itemTouched);

        }
    }
    public interface EscuchadorInterface{
        public void itemSelected(Item anItem);
    }
}

My RecyclerView adapter:

    public class AdapterItemsRecycler extends RecyclerView.Adapter {

    private RealmResults<Item> itemList;
    private Context context;
    private View.OnClickListener listener;
    private Realm realm;


    public AdapterItemsRecycler(RealmResults<Item> itemList, Context context, View.OnClickListener listener) {
        this.itemList = itemList;
        this.context = context;
        this.listener = listener;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.my_list_detail, parent, false);
        view.setOnClickListener(listener);

        ItemViewHolder itemViewHolder = new ItemViewHolder(view);

        return itemViewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        Item item = itemList.get(position);
        ItemViewHolder itemViewHolder = (ItemViewHolder) holder;
        itemViewHolder.loadItem(item);

    }

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

    private class ItemViewHolder extends RecyclerView.ViewHolder{

        private TextView itemText;
        private ImageButton imageButton;

        public ItemViewHolder(View view) {
            super(view);
            itemText = (TextView) view.findViewById(R.id.textViewItemNameTD);
            imageButton = (ImageButton) view.findViewById(R.id.delete);
        }

        public void loadItem(Item item) {

            itemText.setText(item.getName());
            imageButton.setImageResource(R.drawable.trash);

        }

        public ImageButton getImageButton() {
            return imageButton;
        }
    }
}

RecyclerView's detail:

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:design="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    tools:context="com.segunfamisa.sample.bottomnav.MainActivity">

    <ImageButton
        android:id="@+id/delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:tint="#03A9F4"
        android:scaleType="centerInside"
        android:background="#ffffff"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:onClick="deleteItem"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textViewItemNameTD"
        android:textSize="14dp"
        android:textColor="#212121"
        android:background="#ffffff"
        android:padding="10dp"
        android:layout_toRightOf="@+id/delete"/>

    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/arrow"
        android:scaleType="centerInside"
        android:background="#ffffff"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"/>

</RelativeLayout>

Solution

  • Just use RealmRecyclerViewAdapter with the RealmResults directly, which handles synchronization between database and list and adapter automatically.

    public class FragmentMyList
            extends Fragment {
        private RecyclerView recyclerView;
        private EditText editTxt;
        private FloatingActionButton btn;
    
        private AdapterItemsRecycler adapterItemsRecycler;
    
        private Realm realm;
    
        RealmResults<Item> results;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View vistaADevolver = inflater.inflate(R.layout.fragment_my_list, container, false);
            getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    
            Realm.init(getContext());
            realm = Realm.getDefaultInstance();
    
            editTxt = (EditText) vistaADevolver.findViewById(R.id.editText);
            btn = (FloatingActionButton) vistaADevolver.findViewById(R.id.button);
            recyclerView = (RecyclerView) vistaADevolver.findViewById(R.id.recyclerViewToDo);
    
            results = realm.where(Item.class).equalTo("id", 1).findAll();
            final InputMethodManager inputManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    
            adapterItemsRecycler = new AdapterItemsRecycler(results, new ItemsListener());
            recyclerView.setHasFixedSize(true);
            recyclerView.addItemDecoration(new SimpleItemDivider(getActivity()));
            recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
            recyclerView.setAdapter(adapterItemsRecycler);
    
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    String itemName = editTxt.getText().toString();
                    saveIntoDatabase(itemName);
    
                    inputManager.hideSoftInputFromWindow(getView().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
                    editTxt.getText().clear();
                }
            });
            return vistaADevolver;
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            realm.close();
        }
    
        private void saveIntoDatabase(final String itemName) {
            realm.executeTransactionAsync(new Realm.Transaction() {
                @Override
                public void execute(Realm bgRealm) {
                    Item item = bgRealm.createObject(Item.class);
                    item.setName(itemName);
                    item.setPoint(itemName);
                    item.setId(1);
                }
            }, new Realm.Transaction.OnSuccess() {
                @Override
                public void onSuccess() {
                    // Transaction was a success.
                    Log.v("database", "Stored ok");
                }
            }, new Realm.Transaction.OnError() {
                @Override
                public void onError(Throwable error) {
                    // Transaction failed and was automatically canceled.
                    Log.e("database", error.getMessage());
                }
            });
    
        }
    
        class ItemsListener
                implements AdapterView.OnClickListener {
            @Override
            public void onClick(View view) {
                Item itemTouched = results.get(recyclerView.getChildAdapterPosition(view));
                EscuchadorInterface unEscuchador = (EscuchadorInterface) getActivity();
                unEscuchador.itemSelected(itemTouched);
            }
        }
    
        public interface EscuchadorInterface {
            public void itemSelected(Item anItem);
        }
    }
    

    // compile 'io.realm:android-adapters:2.0.0'
    public class AdapterItemsRecycler
            extends RealmRecyclerViewAdapter<Item, ItemViewHolder> {
        private View.OnClickListener listener;
    
        public AdapterItemsRecycler(OrderedRealmCollection<Item> itemList, View.OnClickListener listener) {
            super(itemList, true);
            this.listener = listener;
        }
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            View view = inflater.inflate(R.layout.my_list_detail, parent, false);
            view.setOnClickListener(listener);
            ItemViewHolder itemViewHolder = new ItemViewHolder(view);
            return itemViewHolder;
        }
    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            Item item = getData().get(position);
            ItemViewHolder itemViewHolder = (ItemViewHolder) holder;
            itemViewHolder.loadItem(item);
        }
    
        private static class ItemViewHolder
                extends RecyclerView.ViewHolder {
            private TextView itemText;
            private ImageButton imageButton;
    
            public ItemViewHolder(View view) {
                super(view);
                itemText = (TextView) view.findViewById(R.id.textViewItemNameTD);
                imageButton = (ImageButton) view.findViewById(R.id.delete);
            }
    
            public void loadItem(Item item) {
                itemText.setText(item.getName());
                imageButton.setImageResource(R.drawable.trash);
            }
    
            public ImageButton getImageButton() {
                return imageButton;
            }
        }
    }
    

    private void deleteFromDatabase(final String itemName) {
        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm bgRealm) {
                Item item = bgRealm.where(Item.class).equalTo("name", itemName).findFirst();
                if(item != null) {
                    item.deleteFromRealm();
                }
            }
        }, new Realm.Transaction.OnSuccess() {
            @Override
            public void onSuccess() {
                // Transaction was a success.
                Log.v("database", "Delete ok");
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(Throwable error) {
                // Transaction failed and was automatically canceled.
                Log.e("database", error.getMessage());
            }
        });
    
    }