Java tutorial
/** * 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); } }); } }