Search code examples
androiddesign-patternsobserver-pattern

How do I update a TextView that stores an average of list values


I have an android activity that consists of a List View and a Text View. The Text view displays information about the summed contents of the list view, if the items in the list view are updated then the Text View needs to reflect the change.

Sort of like an observer pattern but with one component reflecting the changes of many rather than the other way round.

The tasks are displayed as items in the list view and the progress can be updated using a seekbar to set the new progress level.

The following method populates the TextView so I need to call this again from inside the SeekBar onStopTrackingProgress Listener.

private void populateOverviewText() {
TextView overview = (TextView) findViewById(R.id.TaskOverview);

if (!taskArrayList.isEmpty()) {

    int completion = 0;
    try {
    completion = taskHandler.getProjectCompletion();
    overview.setText("Project Completion = " + completion);
    } catch (ProjectManagementException e) {
    Log.d("Exception getting Tasks List from project",
        e.getMessage());
    }
}

}

I realise if I want to call the method from the List Adapter then I'll need to make the method accessible but I'm not sure the best approach to do this.


Solution

  • Using DataSetObserver

    I was looking for a solution that didn't involve altering the adapter code, so the adapter could be reused in other situations.

    I acheived this using a DataSetObserver

    The code for creating the Observer is incredibly straight forward, I simply add a call to the method which updates the TextView inside the onChanged() method.

    Attaching the Observer (Added to Activity displaying list)

        final TaskAdapter taskAdapter = new TaskAdapter(this, R.id.list, taskArrayList);
    
        /* Observer */
        final DataSetObserver observer = new DataSetObserver() {
            @Override
            public void onChanged() {
                populateOverviewText();
            }
        };
    
        taskAdapter.registerDataSetObserver(observer);
    

    Firing the OnChanged Method (Added to the SeekBar Listener inside the adapter)

        public void onStopTrackingTouch(SeekBar seekBar) {
        int progress = seekBar.getProgress();
        int task_id = (Integer) seekBar.getTag();
    
        TaskHandler taskHandler = new TaskHandler(DBAdapter
            .getDBAdapterInstance(getContext()));
    
        taskHandler.updateTaskProgress(task_id, progress);
    
        mList.get(position).setProgress(progress);
    
    
        //need to fire an update to the activity
        notifyDataSetChanged();
    
        }