Java tutorial
/* Copyright 2016 Steve Leach Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package org.steveleach.scoresheet.ui; import android.app.*; import android.content.DialogInterface; import android.graphics.Color; import android.os.Bundle; import android.util.Log; import android.view.ContextThemeWrapper; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.TextView; import android.widget.Toast; import org.json.JSONException; import org.steveleach.ihscoresheet.*; import org.steveleach.scoresheet.support.*; import org.steveleach.scoresheet.model.*; /** * Main Activity for the Scoresheet app. * * @author Steve Leach */ public class ScoresheetActivity extends Activity implements ModelAware, DefaultFragmentActivity { private static final String MAIN_FRAGMENT = "MAIN_FRAGMENT"; public static final String STATE_KEY = "MODEL_JSON"; public static final String LOG_TAG = "IHSS"; private ScoresheetModel model = new ScoresheetModel(); private FileManager fileManager = new FileManager(); private JsonCodec jsonCodec = new JsonCodec(); ScoresheetStore scoresheetStore; private SystemContext context; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); context = new AndroidSystemContext(getApplicationContext()); scoresheetStore = new ScoresheetStore(fileManager, jsonCodec, context); showHistory(); } @Override protected void onResume() { super.onResume(); Log.d(LOG_TAG, "ScoresheetActivity.onResume"); model.addListener(this); model.notifyListeners(ModelUpdate.ALL_CHANGED); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); Log.d(LOG_TAG, "ScoresheetActivity.onRestoreInstanceState"); String jsonText = savedInstanceState.getString(STATE_KEY); if (jsonText != null) { try { jsonCodec.fromJson(model, jsonText); model.notifyListeners(ModelUpdate.ALL_CHANGED); } catch (JSONException e) { toast("Error parsing json: " + e.getMessage()); } } } @Override public void onSaveInstanceState(Bundle outState) { Log.d(LOG_TAG, "ScoresheetActivity.onSaveInstanceState"); try { String modelJson = jsonCodec.toJson(model); outState.putCharSequence(STATE_KEY, modelJson); } catch (JSONException e) { toast("Error creating json: " + e.getMessage()); } } public void setFileManager(FileManager fileManager) { this.fileManager = fileManager; scoresheetStore.setFileManager(fileManager); } public void periodButtonClicked(View view) { model.setChanged(true); model.addEvent(new PeriodEndEvent(model.getPeriod())); } public void goalButtonClicked(View view) { String team = getTeamForView(view, R.id.btnHomeGoal); GoalFragment fragment = new GoalFragment(); fragment.setModel(model); fragment.setTeam(team); showFragment(fragment); } private String getTeamForView(View view, int homeId) { if (view.getId() == homeId) { return model.getHomeTeam().getName(); } else { return model.getAwayTeam().getName(); } } public void penaltyButtonClicked(View view) { String team = getTeamForView(view, R.id.btnHomePen); PenaltyFragment fragment = new PenaltyFragment(); fragment.setModel(model); fragment.setTeam(team); showFragment(fragment); } @Override public void onBackPressed() { FragmentManager fm = getFragmentManager(); if (fm.getBackStackEntryCount() > 1) { closeLatestFragment(); } else { super.onBackPressed(); } } public void showFragment(Fragment fragment) { FragmentTransaction tx = getFragmentManager().beginTransaction(); tx.replace(R.id.fragmentContainer, fragment, MAIN_FRAGMENT); tx.addToBackStack(null); tx.commit(); } void showHistory() { HistoryFragment h = new HistoryFragment(); h.setModel(model); showFragment(h); } public void closeFragmentButtonClicked(View view) { closeLatestFragment(); } public void reportButtonClicked(View view) { showGameReport(); } public void closeLatestFragment() { FragmentManager fm = getFragmentManager(); if (fm.getBackStackEntryCount() > 0) { fm.popBackStackImmediate(); } } private void showGameReport() { ReportFragment fragment = new ReportFragment(); fragment.setModel(model); showFragment(fragment); } private void newGame() { yesNoDialog(R.string.clearEventsPrompt, new Runnable() { @Override public void run() { model.reset(); model.notifyListeners(ModelUpdate.ALL_CHANGED); } }); } @Override public void setModel(ScoresheetModel model) { this.model = model; } public ScoresheetModel getModel() { return this.model; } @Override public void onModelUpdated(ModelUpdate update) { updateScores(); } private void updateScores() { CharSequence otText = getText(R.string.overTimeAbbrev); updateScore(R.id.txtHomeScore, model.getHomeGoals()); updateScore(R.id.txtAwayScore, model.getAwayGoals()); updateScore(R.id.txtPeriod, model.getPeriod() > model.getRules().getRegulationPeriods() ? otText : model.getPeriod()); } private void updateScore(int fieldId, Object score) { TextView field = (TextView) findViewById(fieldId); field.setText(score.toString()); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.optionsmenu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { boolean consumed = false; switch (item.getItemId()) { case R.id.menuGameDetails: showGameDetails(); consumed = true; break; case R.id.menuNewGame: newGame(); consumed = true; break; case R.id.menuSave: saveGame(); consumed = true; break; case R.id.menuLoad: loadGame(); consumed = true; break; case R.id.menuRefresh: refreshModel(); consumed = true; break; case R.id.menuAbout: showAbout(); consumed = true; break; case R.id.menuHelp: showHelp(); consumed = true; break; //case R.id.menuTest: // consumed = true; // break; } return consumed; } public void showPlayers(Team team) { PlayersFragment fragment = new PlayersFragment(); fragment.setModel(model); fragment.setTeam(team); showFragment(fragment); } private boolean showGameDetails() { GameFragment fragment = new GameFragment(); fragment.setModel(model); showFragment(fragment); return true; } private void showHelp() { HelpFragment fragment = new HelpFragment(); showFragment(fragment); } private void showAbout() { // Inflate the about message contents View messageView = getLayoutInflater().inflate(R.layout.about, null, false); TextView version = (TextView) messageView.findViewById(R.id.txtAppVersion); String versionText = getApplicationContext().getString(R.string.appVersionText, context.applicationVersion()); version.setText(versionText); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setIcon(R.mipmap.ic_launcher); builder.setTitle(R.string.app_name); builder.setView(messageView); builder.create(); builder.show(); } private void loadGame() { SavesFragment fragment = new SavesFragment(); fragment.configure(model, scoresheetStore); showFragment(fragment); } private void saveGame() { yesNoDialog(R.string.saveGamePrompt, new Runnable() { @Override public void run() { StoreResult result = scoresheetStore.save(model); if (result.success) { model.setChanged(false); model.notifyListeners(ModelUpdate.ALL_CHANGED); } toast(result.text); } }); } public void toast(String message) { Log.d(LOG_TAG, message); Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); } private void refreshModel() { updateScores(); model.sortEvents(); ModelAware visibleFragment = (ModelAware) getVisibleFragment(); if (visibleFragment == null) { // This should not happen showHistory(); } model.notifyListeners(new ModelUpdate()); } public Fragment getVisibleFragment() { return getFragmentManager().findFragmentByTag(MAIN_FRAGMENT); } void yesNoDialog(int promptId, Runnable action) { questionDialog(getString(promptId), getString(R.string.yesOption), getString(R.string.noOption), action); } void yesNoDialog(String prompt, Runnable action) { questionDialog(prompt, getString(R.string.yesOption), getString(R.string.noOption), action); } private void questionDialog(String prompt, String yesButton, String noButton, final Runnable action) { DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int button) { switch (button) { case DialogInterface.BUTTON_POSITIVE: action.run(); break; case DialogInterface.BUTTON_NEGATIVE: break; } } }; ContextThemeWrapper wrapper = new ContextThemeWrapper(this, R.style.AppDialog); AlertDialog.Builder builder = new AlertDialog.Builder(wrapper); AlertDialog dialog = builder.setTitle(getString(R.string.confirmAlertTitle)).setMessage(prompt) .setPositiveButton(yesButton, listener).setNegativeButton(noButton, listener).create(); dialog.show(); int color = getResources().getColor(R.color.appdark); TextView tv = (TextView) getDialogView(dialog, "android:id/alertTitle"); tv.setTextColor(color); View divider = getDialogView(dialog, "android:id/titleDivider"); divider.setBackgroundColor(color); } private View getDialogView(AlertDialog dialog, String resourceName) { int textViewId = dialog.getContext().getResources().getIdentifier(resourceName, null, null); return dialog.findViewById(textViewId); } @Override public void showDefaultFragment() { showHistory(); } public ScoresheetStore getStore() { return scoresheetStore; } public String playerNum(int playerNum) { if (playerNum == 0) { return getString(R.string.benchShortCode); } else { return Integer.toString(playerNum); } } public String playerNum(GameEvent event) { return playerNum(event.getPlayer()); } /** * Return the list position for a context menu selection on an item in a ListView. */ public static int listContextMenuPosition(MenuItem item) { return ((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).position; } }