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 de.uni_koblenz_landau.apow.helper.ListViewItem; import de.uni_koblenz_landau.apow.tasks.SettingsInterface; import de.uni_koblenz_landau.apow.tasks.SettingsTask; import de.uni_koblenz_landau.apow.tasks.SettingsUpdateInterface; import de.uni_koblenz_landau.apow.tasks.SettingsUpdateTask; import de.uni_koblenz_landau.apow.tasks.TaskActivity; import de.uni_koblenz_landau.apow.tasks.TaskActivityReference; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.NavUtils; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; /** * Fragment for showing and updating settings. * * @author Martin Landua * */ public class SettingsFragment extends Fragment implements SettingsInterface, SettingsUpdateInterface, TaskActivity { // Constants private static final String ARG_SETTINGS = "settings"; private static final String ARG_LOCATIONS = "locations"; public static final int STATUS_OK = 0; public static final int STATUS_ERROR = 1; // Tasks private SettingsUpdateTask mSettingsUpdateTask; private SettingsTask mSettingsTask; // UI Variables private List<ListViewItem> mLocations; private ListViewItem mSettings; private String mUsername; private String mPassword; // UI references private EditText mUsernameView; private EditText mPasswordView; private Spinner mLocationsView; private View mFormView; private View mStatusView; private TextView mStatusMessageView; /** * Empty constructor for Instantiation */ public SettingsFragment() { } @Override public void onCreate(Bundle savedInstanceState) { setHasOptionsMenu(true); super.onCreate(savedInstanceState); // Re-attach Tasks. TaskActivityReference.getInstance().attach(SettingsUpdateTask.TASK_ID, this); TaskActivityReference.getInstance().attach(SettingsTask.TASK_ID, this); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.settings_fragment, container, false); // Create UI references. mUsernameView = (EditText) view.findViewById(R.id.settings_username); mPasswordView = (EditText) view.findViewById(R.id.settings_password); mLocationsView = (Spinner) view.findViewById(R.id.settings_locations); mFormView = view.findViewById(R.id.settings_form); mStatusView = view.findViewById(R.id.settings_status); mStatusMessageView = (TextView) view.findViewById(R.id.settings_status_message); // Restore UI from saved instance or load data. if (savedInstanceState != null) { mSettings = savedInstanceState.getParcelable(ARG_SETTINGS); if (mSettings != null) { mLocations = savedInstanceState.getParcelableArrayList(ARG_LOCATIONS); ArrayAdapter<ListViewItem> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, mLocations); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mLocationsView.setAdapter(adapter); } } else { loadSettings(); } return view; } @Override public void onDestroy() { super.onDestroy(); // Detach tasks for preventing memory leaks. TaskActivityReference.getInstance().detach(SettingsUpdateTask.TASK_ID); TaskActivityReference.getInstance().detach(SettingsTask.TASK_ID); } @Override public void onSaveInstanceState(Bundle savedInstanceState) { // Save UI data to instance. savedInstanceState.putParcelable(ARG_SETTINGS, mSettings); savedInstanceState.putParcelableArrayList(ARG_LOCATIONS, (ArrayList<ListViewItem>) mLocations); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.settings, menu); super.onCreateOptionsMenu(menu, inflater); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == android.R.id.home) { NavUtils.navigateUpFromSameTask(getActivity()); return true; } if (id == R.id.settings_action_save) { save(); return true; } if (id == R.id.settings_action_cancel) { NavUtils.navigateUpFromSameTask(getActivity()); return true; } return super.onOptionsItemSelected(item); } /** * Checks input and saves settings to database. */ private void save() { // Abort if task is already running. if (mSettingsUpdateTask != null) { return; } // Reset errors. mUsernameView.setError(null); mPasswordView.setError(null); // Store UI values. mUsername = mUsernameView.getText().toString(); mPassword = mPasswordView.getText().toString(); Boolean cancel = false; View focusView = null; // Validate UI input. if (TextUtils.isEmpty(mUsername)) { mUsernameView.setError(getString(R.string.error_field_required)); focusView = mUsernameView; cancel = true; } if (TextUtils.isEmpty(mPassword)) { mPasswordView.setError(getString(R.string.error_field_required)); focusView = mPasswordView; cancel = true; } else if (mPassword.length() < 4) { mPasswordView.setError(getString(R.string.error_invalid_password)); focusView = mPasswordView; cancel = true; } // If there are errors cancel, else save to database. if (cancel) { focusView.requestFocus(); } else { // Update setting object. mSettings.setField1(mUsername); mSettings.setField2(mPassword); mSettings.setId2(((ListViewItem) mLocationsView.getSelectedItem()).getId()); // Show progress window. mStatusMessageView.setText(R.string.settings_progress); showProgress(true); // Start update task. mSettingsUpdateTask = new SettingsUpdateTask(); TaskActivityReference.getInstance().addTask(SettingsUpdateTask.TASK_ID, mSettingsUpdateTask, this); mSettingsUpdateTask.execute(mSettings); } } /** * Called by update task, when update is finished. */ @Override public void onDataUpdateFinished(int result) { mSettingsUpdateTask = null; // Hide progress window. showProgress(false); if (result == STATUS_OK) { // Leave activity. NavUtils.navigateUpFromSameTask(getActivity()); } else if (result == STATUS_ERROR) { Toast.makeText(getActivity(), R.string.login_setup_login_wrong, Toast.LENGTH_SHORT).show(); } } /** * Starts task to load settings. */ private void loadSettings() { // Abort if task is already running. if (mSettingsTask != null) { return; } // Start settings task. mSettingsTask = new SettingsTask(); TaskActivityReference.getInstance().addTask(SettingsTask.TASK_ID, mSettingsTask, this); mSettingsTask.execute(); } /** * Called by settings task, when loading is finished. */ @Override public void onSettingsFetched(ListViewItem settings, List<ListViewItem> locations) { mSettingsTask = null; // If result is not empty, update UI, else show error message. if (settings != null && locations != null) { mSettings = settings; mUsernameView.setText(mSettings.getField1()); mPasswordView.setText(mSettings.getField2()); mLocations = locations; ArrayAdapter<ListViewItem> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, locations); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mLocationsView.setAdapter(adapter); int position = -1; for (int i = 0; i < adapter.getCount(); i++) { if (adapter.getItem(i).getId() == settings.getId()) { position = i; break; } } mLocationsView.setSelection(position); } else { Toast.makeText(getActivity(), R.string.error_database, Toast.LENGTH_SHORT).show(); } } /** * Shows the progress UI and hides the form. Source: Android Developers * Login Example */ private void showProgress(final boolean show) { InputMethodManager inputManager = (InputMethodManager) getActivity() .getSystemService(FragmentActivity.INPUT_METHOD_SERVICE); if (getActivity().getCurrentFocus() != null) { inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } 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); } }); } }