Home > Enterprise >  How is my recyclerview item meant to communicate with the database?
How is my recyclerview item meant to communicate with the database?

Time:04-20

I have recyclerview with each item holding some buttons and text.

I am setting my onViewClickListener in the ViewHolder. I have a Room database initialized in the MainActivity.

In terms of good app architecture, how should I change the data in my database once my OnClickListener triggers?

Do I pass the database as a parameter to the adapter then the view holder?
OR
Do I get the database through a getDatabase method that I implement?

What is the best way to go about this? I am open to any suggestion/design pattern.
How is something like this generally handled?

CodePudding user response:

Best practise is to keep the database in your AppCompatActivity.

If you display database data in that recyclerView you should create an ArrayList filled with those data and pass it to the recyclerViewAdapter in the constructor like MyRecyclerViewAdapter myRecyclerViewAdapter = new MyRecyclerViewAdapter(myData)

Then everytime you change something from that list (from your activity) you just call notify method based on your action. General one is myRecyclerViewAdapter.notifyDataSetChanged(). But with lot data it's more efficient to use more specific notify methods.

And if the database should change based on some event in recyclerView, for example by the onViewClickListener. You should create an interface in which you would pass the change and then apply the change to the database in your AppCompatActivity.

CodePudding user response:

You should keep your database (and strongly advise you to use the data with ViewModel) in your activity. You can make changes on data of recyclerview item by using weakreference and interface. Here is example of activity and adapter.

public class MyActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private MyObjectAdapter adapter;
    private final List<MyObject> myObjectList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
    
        //define your views here..
    
        setAdapter();
        getData();
    }

    private void setAdapter(){
        adapter = new MyObjectAdapter(myObjectList, new 
MyObjectAdapter.IObjectClickListener() {
            @Override
            public void onButtonOneClick(MyObject myObject) {
                //do button one operation with object item;
            }

            @Override
            public void onButtonTwoClick(MyObject myObject) {
                //do button two operation with object item;
            }
        });
    }

     private void getData(){
        //Get your data from database and pass add them all into our 
        //myObjectList
        myObjectList.addAll(objects); //Suppose objects come from database
        adapter.notifyDataSetChanged();
    }
}

And adapter class is like

public class MyObjectAdapter extends RecyclerView.Adapter<MyObjectAdapter.ObjectViewHolder> {
    private final List<MyObject> myObjects;
    private final IObjectClickListener listener; //defined at the bottom

    public MyObjectAdapter(List<MyObject> myObjects, IObjectClickListener listener) {
        this.myObjects = myObjects;
        this.listener = listener;
    }

    /*
    ..
    Other methods of adapter are here
    ..
    */

    public class ObjectViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
        private Button buttonOne, buttonTwo;
        private WeakReference<IObjectClickListener> reference;

        public ObjectViewHolder(@NonNull View itemView) {
            super(itemView);

            //define your views here
            reference = new WeakReference<>(listener);

            buttonOne.setOnClickListener(this);
            buttonTwo.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
        if (v == buttonOne){
            reference.get().onButtonOneClick(myObjects.get(getAdapterPosition()));
        } else if (v == buttonTwo){
            reference.get().onButtonTwoClick(myObjects.get(getAdapterPosition()));
        }
    }

    public interface IObjectClickListener{
        void onButtonOneClick(MyObject myObject);

        void onButtonTwoClick(MyObject myObject);
    }
}
  • Related