CSCI 490E/680K Assignment 4b - Android Programming - Spring 2012

03/19/2012 - first draft


Overview

In this assignment you will add two main features to the previous WeatherLog assignment.  In addition to adding new Weather log records, you will now write code to support Edit and Delete operations on log items.  This will involve changes to one xml file as well as an additional Activity (to implement the Edit operation) and other code changes.

In order to to support Edit and Delete, there must be a way for a user to select a log item which is to be edited or deleted. One way to do this is to put an Edit and a Delete button on each log item.  Pressing one of these Buttons will then execute the operation on the item containing that particular Button. So you will first need to modify the xml file that defines a log item.  Arrange to have the two Buttons on the right side of the item's layout, stacked one above the other.  Understand that each item will have its own set of Buttons. You will need to modify the Adapter's getView() for this.  Also note that even if you provide the Buttons with id's, you will need some way to identify the specific log item (one of many) that has been selected. (See "Determining..." below.)

Some Layout Identification Details 

You can make your single-item Layout consist of two LinearLayouts arranged horizontally.  The left-hand side is the three TextView displays (or four - see "Determining..." below); the right-hand side is the two Buttons.  In your Button response callback method, you will get a View argument - let's call it view.  This is the View of the pressed Button.  You can then do the following:

// get the parent of the Button - the right-hand sub-layout
LinearLayout buttonLayout   = (LinearLayout)view.getParent();
// get the Buttons sub-layout's parent - the root Layout 
LinearLayout textViewLayout = buttonLayout.getParent();

Now textViewLayout is the root layout of this whole log item, which is what you need to access the individual widgets in this log item's layout.  So, for example, you can:

TextView temperature = (TextView)textViewLayout.findViewById(R.id.temp_id);  // "temp_id" is your name in the xml
String s = (String)temperature.getText();

You can do this to obtain values to be sent to the Edit Activity for alteration, or to get the "hidden" ID (see "Determining..." below).

Edit

If Edit has been selected for an item, you will need to obtain the two editable TextView contents (temperature and notes) from the displayed item and pass that information to a new Activity (EditActivity) so that the current log item data can be displayed for editing.  You can use putExtra() to pass data to the EditActivity intent.  Create and specify a new request code so that when your onActivityResult() is called, you can determine whether to update a current data record or add a new data record (using the returned getStringExtra()) data.

Note that the Edit screen and the Add screen could be the same - the user either fills in blank EditTexts or alters EditTexts with current values.  You can use the same xml file for both Edit and Add Activities and operations.

Don't forget to add the new EditActivity to the manifest file.

Delete

If delete has been selected, you do not need to call a separate Activity.  Just determine what data record should be deleted and remove it. (See below.)

Determining What Data Record corresponds with the Selected Display Log Item

Assuming you know which display item has been selected (see code above), you can obtain displayed Strings (temperature, notes, and date/time).  While unlikely, there is no guarantee that these values might not be duplicated in two or more log items.  We need a way to determine which of the data records in the Adapter's data store corresponds to the data to be edited or deleted.  One way to do this is to add a field to the data record class that is guaranteed to be unique - and to include it as a hidden TextView in the xml layout for a log item.

Do this by defining a static int (call it ID) in the data record class.  Initialize it to 0 in the declaration, and store the current value as an instance variable in each data record object's constructor.  Then increment the ID (for the next new data record).  Then in the Adapter's getView() be sure to store the String version of this data field into the layout.  (It will not be visible - although you might want to display it during development to visually confirm its value.)

Then, when it is time to update or remove a record, pass this value as an argument to your updateRec() or removeRec() - which you will write as utility methods of your data record class.  These methods will search the data ArrayList for a match and then perform the required operation on the found item.  Notice that you cannot depend on an exact correspondence between the ID and the ArrayList index number.  If you just Add items, they will match: ID = 0, index = 0; ID = 1, index = 1 etc.  But, for example, after removing record with index 1, you will still have indexes of 0, 1, 2, 3, etc. but you will have ID's of 0, 2, 3, etc.

(This is as it should be - we should not be able to find the record with ID=1 after it has been removed.  Of course, since the item with ID 1 will have been removed from the display, your code would not be looking for it, either. But what would happen if you got an ID of 2 from the display and then tried to use the index of 2 to delete or edit?)