C, U and D are still left, so here they come.
What we finally have to do now is adding two OnClickListeners to our buttons (to write data back and to delete). Now that you are through the 3 last parts, I think you already have an idea where and how to do this. onCreate of LeaseActivity should look as follows:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_lease); editTextItem = (EditText) findViewById(R.id.activity_lease_item); editTextComment = (EditText) findViewById(R.id.activity_lease_comment); spinnerPerson = (Spinner) findViewById(R.id.activity_lease_person); buttonSave = (Button) findViewById(R.id.activity_lease_save); buttonDelete = (Button) findViewById(R.id.activity_lease_delete); Intent intent = getIntent(); Long leaseId = intent.getLongExtra("lease_id", 0); if(leaseId != 0 ) { DaoSession daoSession = ((LeaseApplication) getApplicationContext()).getDaoSession(); LeaseDao leaseDao = daoSession.getLeaseDao(); lease = leaseDao.load(leaseId); if(lease != null) { editTextItem.setText(lease.getItem()); editTextComment.setText(lease.getComment()); } } buttonSave.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { lease.setItem(String.valueOf(editTextItem.getText())); lease.setComment(String.valueOf(editTextComment.getText())); DaoSession daoSession = ((LeaseApplication) getApplicationContext()).getDaoSession(); daoSession.insertOrReplace(lease); finish(); } }); buttonDelete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { DaoSession daoSession = ((LeaseApplication) getApplicationContext()).getDaoSession(); daoSession.delete(lease); finish(); } }); }
As you can see, we are taking data from our EditTexts and move it into the object from our model. Then, we call one of two methods (delete
() or insertOrUpdate()), that will take care of of our data. That’s it, again no SQL at all!
If you run the app now, try two things. Open one item of your RecyclerView and edit data. If you hit the save-button and re-open that item,
everything will be there, so we can see our data is saved – anyhow, if you delete something, the RecyclerView still shows it.
What’s wrong? Deletions not working? – They work, BUT the RecyclerView isn’t notified about a changed dataset. We’ll find a way of quickly
displaying our data.
Usually we would be dealing with Android lifecycle now, again, but due to the reason our topic is GreenDAO I think we can ignore good
coding guidelines and will do the following: we override onResume (you know it, right-click –> generate –> select onResume-Method) and enter the
following code:
DaoSession daoSession = ((LeaseApplication) getApplicationContext()).getDaoSession(); LeaseDao leaseDao = daoSession.getLeaseDao(); List<Lease> leaseList = leaseDao.loadAll(); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.main_activity_recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); MainActivityListAdapter adapter = new MainActivityListAdapter(leaseList, this); recyclerView.setAdapter(adapter);
If it looks familiar to you, then I am not wondering about that – it is the same code as in onCreate. For our example-app it doesn’t make
any difference, but you might remove that block from onCreate, because if onCreate is called during startup of the app or when the Activity is
displayed, onResume will also be called anyways.
After this little trick our RecyclerView will get a brand-new Adapter and a brand-new Lease-List (basically) everytime it comes on screen (or e.g.
if the phone changes orientation) – that’s far from efficient, but for our example it’ll do the job.
Creating new Entities
We still need a way to insert new Leases into our database. Let us create a menu-entry in MainActivity for that. Open main_menu.xml from
the folder res/menu, it should look as follows:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.devteam83.tutorials.leasegreendao.MainActivity"> <item android:id="@+id/action_settings" android:title="@string/action_settings" android:orderInCategory="100" android:showAsAction="never" /> </menu>
We can re-use the existing item, i.e. we replace the id and its title. if you set showAsAction to “always” we don’t need to always open the
menu, so that sounds like a good idea. Mine looks like that now:
<item android:id="@+id/action_new" android:title="new" android:showAsAction="always" />
Would be quite useful, if it would also do something (it does not, yet). So we go to MainActivity.java and change the method
onOptionsItemSelected(MenuItem item). We adjust the line “if (id == R.id.action_settings) {” to “if (id == R.id.action_new) {“. The menu-entry will
do roughly the same as in the onClick event of the ViewHolder – it fires an Intent to launch LeaseActivity, but with ID 0:
if (id == R.id.action_new) { Intent intent = new Intent(this, LeaseActivity.class); intent.putExtra("lease_id", 0); this.startActivityForResult(intent, 1); return true; }
To make LeaseActivity not get confused by this, we have to have a look it. Open LeaseActivity.java and have a look at onCreate. We are
already checking, if leaseId, i.e. the ID we got from the Intent, is 0, so we simply create an else-block for our purposes. If the ID is not 0, we
read the lease from the DB, but our new leases are not in the DB, yet. Let us create a new Lease in this case:
if(leaseId != 0 ) { DaoSession daoSession = ((LeaseApplication) getApplicationContext()).getDaoSession(); LeaseDao leaseDao = daoSession.getLeaseDao(); lease = leaseDao.load(leaseId); if(lease != null) { editTextItem.setText(lease.getItem()); editTextComment.setText(lease.getComment()); } } else { lease = new Lease(); }
That would be fine if we could select a person in the Spinner, but that is not the case, so I’ll add some code to insert a new person each
time we have a new Lease – this goes to LeaseActivity and replaces the existing method:
buttonSave.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { lease.setItem(String.valueOf(editTextItem.getText())); lease.setComment(String.valueOf(editTextComment.getText())); DaoSession daoSession = ((LeaseApplication) getApplicationContext()).getDaoSession(); Person person = new Person(); person.setName("John Doe "+ Math.random()); PersonDao personDao = daoSession.getPersonDao(); personDao.insertOrReplace(person); lease.setPerson(person); daoSession.insertOrReplace(lease); finish(); } });
What we can see from this, is that with GreenDAO you don’t have to check yourself, if the entity is new (and therefore has to be inserted)
or if it already exists (and has to be updated). Just relax and let GreenDAO do that work 😉
WARNING! If you have launched the app before we made this last change, then your app will crash in MainActivity, because there is no Person
in our Lease. If that’s the case, uninstall the app from your emulator or the phone you use and simply launch it again from Android Studio. The
database will be brand new after that and the app will run again.
Next steps
We are finally at the end of our tutorials, but there are still a few things to do in our app. I think, due to the reason we covered all
different needed actions, you might be able to implement these yourself:
– create Activities for creating, updating etc. Person-entities
– populate the Spinner in LeaseActivity
– save the selected Person in LeaseActivity
– get rid of the dirty hacks I used
– proper handling of lifecycle methods
I am sorry for using dirty shortcuts here and there – I guess if I would have done everything in a proper way there would still be 14 parts
missing, hopefully you forgive me 😉
Topics to read on
If this was your first contact with GreenDAO or maybe even Android programming at all: Congratulations!
Maybe you should have a look at the following resources:
– greenrobots website (creators of greenDAO)
– Android Lifecycle at Android Developers
– if you are new to Android programming at all, you can check out “Android Programming: The Big Nerd Ranch Guide” (no, we have no relation to the
book or the authors) – easy to read, a lot of topics covered (but no OR-mappers 😉 )
I hope you enjoyed this series as much as I did, thanks for following through all 4 parts.
If you have questions, comments, need help with the “Next steps” – leave a comment!
great tuts thank u