de.uni_koblenz_landau.apow.PatientListFragment.java Source code

Java tutorial

Introduction

Here is the source code for de.uni_koblenz_landau.apow.PatientListFragment.java

Source

/**
 * Apow - a mobile EHR Management System for low-resource environments
 * in developing countries, exemplified by rural Ghana
 * Copyright (C) 2014 Martin Landua
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
 */

package de.uni_koblenz_landau.apow;

import java.util.ArrayList;
import java.util.List;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.ActionBar;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.ExpandableListView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ExpandableListView.OnGroupCollapseListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import de.uni_koblenz_landau.apow.db.PatientAdapter;
import de.uni_koblenz_landau.apow.helper.ListViewItem;
import de.uni_koblenz_landau.apow.tasks.PatientListTask;
import de.uni_koblenz_landau.apow.tasks.PatientListInterface;
import de.uni_koblenz_landau.apow.tasks.SyncInterface;
import de.uni_koblenz_landau.apow.tasks.SyncTask;
import de.uni_koblenz_landau.apow.tasks.TaskActivity;
import de.uni_koblenz_landau.apow.tasks.TaskActivityReference;

/**
 * Fragment for showing a list of patients.
 * 
 * @author Martin Landua
 * 
 */
public class PatientListFragment extends Fragment implements PatientListInterface, SyncInterface, TaskActivity {

    // Constants
    private static final String ARG_PATIENTS = "patients";
    private static final String ARG_LAST_EXPANDED = "last_expanded";
    private static final String ARG_PROGRESS = "progress";
    public static final int STATUS_SYNC_FETCH_FACTS = 1;
    public static final int STATUS_SYNC_FETCH_USERDATA = 2;
    public static final int STATUS_SYNC_UPLOAD_USERDATA = 3;
    public static final int STATUS_CONNECTION_ERROR = 4;
    public static final int STATUS_ERROR = 5;
    public static final int STATUS_OK = 6;

    // Tasks
    private PatientListTask mPatientListTask;
    private SyncTask mSyncTask;

    // UI Variables
    private int mLastExpandedPosition = -1;
    private List<ListViewItem> mPatients;
    private Boolean mProgress;

    // UI references
    private ExpandableListView mListView;
    private View mFormView;
    private View mStatusView;
    private TextView mStatusMessageView;

    /**
     * Empty constructor for Instantiation
     */
    public PatientListFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        setHasOptionsMenu(true);
        super.onCreate(savedInstanceState);

        // Re-attach Tasks.
        TaskActivityReference.getInstance().attach(PatientListTask.TASK_ID, this);
        TaskActivityReference.getInstance().attach(SyncTask.TASK_ID, this);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.patient_list_fragment, container, false);

        // Create UI references.
        mFormView = view.findViewById(R.id.patient_list_fragment_form);
        mStatusView = view.findViewById(R.id.patient_list_fragment_status);
        mStatusMessageView = (TextView) view.findViewById(R.id.patient_list_fragment_status_message);
        mListView = (ExpandableListView) view.findViewById(R.id.patient_list_fragment_listview);
        mListView.setEmptyView(view.findViewById(android.R.id.empty));
        mListView.getEmptyView().setVisibility(ListView.GONE);
        mListView.setOnGroupExpandListener(new OnGroupExpandListener() {
            @Override
            public void onGroupExpand(int groupPosition) {
                if (mLastExpandedPosition != -1 && groupPosition != mLastExpandedPosition) {
                    mListView.collapseGroup(mLastExpandedPosition);
                }
                mLastExpandedPosition = groupPosition;
            }
        });
        mListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
            @Override
            public void onGroupCollapse(int groupPosition) {
                mLastExpandedPosition = -1;
            }
        });

        // Restore UI from saved instance or load data.
        if (savedInstanceState != null) {
            mLastExpandedPosition = savedInstanceState.getInt(ARG_LAST_EXPANDED, -1);
            mPatients = savedInstanceState.getParcelableArrayList(ARG_PATIENTS);
            PatientAdapter adapter = new PatientAdapter(this.getActivity(), mPatients);
            mProgress = savedInstanceState.getBoolean(ARG_PROGRESS);
            mListView.setAdapter(adapter);
            if (mLastExpandedPosition != -1) {
                mListView.expandGroup(mLastExpandedPosition);
            }
        } else {
            mProgress = false;
            mLastExpandedPosition = -1;
            searchPatients("", false);
        }
        showProgress(mProgress);
        return view;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // Detach tasks for preventing memory leaks.
        TaskActivityReference.getInstance().detach(PatientListTask.TASK_ID);
        TaskActivityReference.getInstance().detach(SyncTask.TASK_ID);
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        savedInstanceState.putInt(ARG_LAST_EXPANDED, mLastExpandedPosition);
        savedInstanceState.putParcelableArrayList(ARG_PATIENTS, (ArrayList<ListViewItem>) mPatients);
        savedInstanceState.putBoolean(ARG_PROGRESS, mProgress);
        super.onSaveInstanceState(savedInstanceState);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.patient_list_action_sync) {
            startSync();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * Start task to search for patients.
     * @param search Query
     * @param reset Close expanded entries
     */
    public void searchPatients(String search, Boolean reset) {
        // Abort if task is already running.
        if (mPatientListTask != null) {
            return;
        }

        // Close expanded entries
        if (reset) {
            mLastExpandedPosition = -1;
        }

        // Start task.
        mPatientListTask = new PatientListTask();
        TaskActivityReference.getInstance().addTask(PatientListTask.TASK_ID, mPatientListTask, this);
        mPatientListTask.execute(search);
    }

    /**
     * Called by PatientListTask, when patients are fetched.
     */
    @Override
    public void onPatientsFetched(List<ListViewItem> patients) {
        mPatientListTask = null;

        // If result is not empty, update UI, else show error message.
        if (patients != null) {
            mPatients = patients;
            PatientAdapter adapter = new PatientAdapter(this.getActivity(), patients);
            mListView.setAdapter(adapter);

            // If only one patient, expand it.
            if (mPatients.size() == 1) {
                mLastExpandedPosition = 0;
            }
            if (mLastExpandedPosition != -1 && mPatients.size() != 0) {
                mListView.expandGroup(mLastExpandedPosition);
            }

        } else {
            Toast.makeText(getActivity(), R.string.error_database, Toast.LENGTH_SHORT).show();
        }
    }

    /**
      * Start task to sync data.
      */
    public void startSync() {
        // Abort if task is already running.
        if (mSyncTask != null) {
            return;
        }
        showProgress(true);

        // Start task.
        mSyncTask = new SyncTask();
        TaskActivityReference.getInstance().addTask(SyncTask.TASK_ID, mSyncTask, this);
        mSyncTask.execute();
    }

    @Override
    public void updateStatus(int status) {
        String message = "";
        switch (status) {
        case STATUS_SYNC_FETCH_FACTS:
            message = getString(R.string.patient_list_status_fetch_facts);
            break;
        case STATUS_SYNC_FETCH_USERDATA:
            message = getString(R.string.patient_list_status_fetch_userdata);
            break;
        case STATUS_SYNC_UPLOAD_USERDATA:
            message = getString(R.string.patient_list_status_upload_userdata);
            break;
        }

        mStatusMessageView.setText(message);
    }

    @Override
    public void onSyncFinished(Integer status) {
        mSyncTask = null;
        showProgress(false);
        if (status == STATUS_OK) {
            searchPatients("", true);
        } else if (status == STATUS_CONNECTION_ERROR) {
            Toast.makeText(getActivity(), R.string.error_connection, Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getActivity(), R.string.error, Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * Shows the progress UI and hides the form. Source: Android Developers
     * Login Example
     */
    private void showProgress(final boolean show) {
        mProgress = show;
        InputMethodManager inputManager = (InputMethodManager) getActivity()
                .getSystemService(FragmentActivity.INPUT_METHOD_SERVICE);
        if (getActivity().getCurrentFocus() != null) {
            inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(),
                    InputMethodManager.HIDE_NOT_ALWAYS);
        }

        ActionBar actionBar = getActivity().getActionBar();
        if (actionBar != null) {
            if (show) {
                actionBar.hide();
            } else {
                actionBar.show();
            }
        }
        int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);

        mStatusView.setVisibility(View.VISIBLE);
        mStatusView.animate().setDuration(shortAnimTime).alpha(show ? 1 : 0)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        mStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
                    }
                });

        mFormView.setVisibility(View.VISIBLE);
        mFormView.animate().setDuration(shortAnimTime).alpha(show ? 0 : 1)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        mFormView.setVisibility(show ? View.GONE : View.VISIBLE);
                    }
                });
    }
}