diff --git a/.idea/misc.xml b/.idea/misc.xml index 57b25ae..624b66e 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -29,7 +29,7 @@ - + diff --git a/app/build.gradle b/app/build.gradle index 4cae6e5..d85c4ab 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,5 +28,6 @@ dependencies { compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support:design:25.3.1' compile 'com.android.support:support-v4:25.3.1' + compile 'com.android.support.constraint:constraint-layout:1.0.2' testCompile 'junit:junit:4.12' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 373078d..4c140c3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,22 +11,26 @@ android:supportsRtl="true" android:theme="@style/AppTheme"> + android:theme="@style/AppTheme.NoActionBar" + android:windowSoftInputMode="adjustResize"> + - + + + \ No newline at end of file diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/HighscoreActivity.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/HighscoreActivity.java new file mode 100644 index 0000000..556d2ea --- /dev/null +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/HighscoreActivity.java @@ -0,0 +1,58 @@ +package de.hwr_berlin.it14.postgrachelor; + +import android.content.Intent; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.widget.ListView; +import android.widget.TextView; + +import de.hwr_berlin.it14.postgrachelor.Utils.Conversion; +import de.hwr_berlin.it14.postgrachelor.Utils.HighscoreAdapter; + +public class HighscoreActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_highscore); + + if (getActionBar() != null) { + getActionBar().setDisplayHomeAsUpEnabled(true); + getActionBar().setDisplayShowHomeEnabled(true); + } else if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + } + + // Get the Intent that started this activity and extract the string + Intent intent = getIntent(); + String categoryID = intent.getStringExtra("CategoryID"); + String categoryName = intent.getStringExtra("CategoryName"); + String categoryCount = intent.getStringExtra("CategoryCount"); + + ListView listView = (ListView) findViewById(R.id.category_listview); + HighscoreAdapter adapter = new HighscoreAdapter(Conversion.strToInt(categoryCount, 2), Conversion.strToInt(categoryID, -1), getApplicationContext()); + listView.setAdapter(adapter); + + setTitle(categoryName); + + adapter.notifyDataSetChanged(); + } + + @Override + public boolean onSupportNavigateUp() { + onBackPressed(); + return true; + } + + @Override + public boolean onNavigateUp() { + onBackPressed(); + return true; + } + + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + super.onSaveInstanceState(savedInstanceState); + } +} diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/LoginFragment.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/LoginFragment.java index 2cc643a..cbccace 100644 --- a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/LoginFragment.java +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/LoginFragment.java @@ -1,11 +1,13 @@ package de.hwr_berlin.it14.postgrachelor; +import android.content.Context; import android.os.Bundle; import android.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.EditText; @@ -55,6 +57,11 @@ public class LoginFragment extends Fragment { } catch (NotInstantiatedException e) { e.printStackTrace(); } + + InputMethodManager mgr = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + mgr.hideSoftInputFromWindow(v.getWindowToken(), 0); + + } }); diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/MainActivity.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/MainActivity.java index 2cb7ec7..ef96942 100644 --- a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/MainActivity.java +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/MainActivity.java @@ -3,6 +3,7 @@ package de.hwr_berlin.it14.postgrachelor; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.os.Bundle; +import android.support.v4.widget.SwipeRefreshLayout; import android.util.Log; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; @@ -10,6 +11,7 @@ import android.view.Menu; import android.view.MenuItem; import de.hwr_berlin.it14.postgrachelor.Exceptions.NotInstantiatedException; +import de.hwr_berlin.it14.postgrachelor.Exceptions.NotLoggedInException; import de.hwr_berlin.it14.postgrachelor.Services.GameService; import de.hwr_berlin.it14.postgrachelor.Services.HighscoreService; import de.hwr_berlin.it14.postgrachelor.Services.LoginService; @@ -24,6 +26,7 @@ public class MainActivity extends AppCompatActivity { } private static final String NAME = "MainActivity"; + private int fragmentState = 0; private FragmentManager myFragmentManager; private MainFragment mainFragment; private LoginFragment loginFragment; @@ -33,6 +36,7 @@ public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Log.d("Activity fragment", "create"); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); @@ -45,20 +49,27 @@ public class MainActivity extends AppCompatActivity { questionEndFragment = QuestionEndFragment.newInstance(); questionFragment = QuestionFragment.newInstance(); - LoginService.instantiate(this); - HighscoreService.instantiate(this); - GameService.initialize(this); + + if (savedInstanceState != null) { + this.fragmentState = savedInstanceState.getInt("selected fragment"); + } } @Override protected void onStart() { super.onStart(); + final MainActivity that = this; LoginService.addLoginEventListener(NAME, new LoginService.OnLoginEventListener() { @Override public void onLoginEvent(String name, String uid) { Log.d("Activity fragment", "onLogin - name: " + name + " - uid: " + uid); that.selectFragment(FragmentState.MAIN); + try { + HighscoreService.updateHighscores(); + } catch (NotInstantiatedException | NotLoggedInException e) { + e.printStackTrace(); + } } @Override @@ -75,11 +86,32 @@ public class MainActivity extends AppCompatActivity { that.selectFragment(FragmentState.QUESTION); else if (previous == GameService.States.ON_HOLD_RESULT && state == GameService.States.END) { that.selectFragment(FragmentState.QUESTION_END); + try { + HighscoreService.updateHighscores(); + } catch (NotInstantiatedException | NotLoggedInException e) { + e.printStackTrace(); + } } else if (state == GameService.States.PAUSED || state == GameService.States.END) { that.selectFragment(FragmentState.MAIN); } } }); + HighscoreService.instantiate(this); + LoginService.instantiate(this); + GameService.initialize(this); + + //this.selectFragment(this.fragmentState); + } + + @Override + public void onBackPressed() + { + this.selectFragment(FragmentState.MAIN); + try { + HighscoreService.updateHighscores(); + } catch (NotInstantiatedException | NotLoggedInException e) { + e.printStackTrace(); + } } @Override @@ -105,6 +137,7 @@ public class MainActivity extends AppCompatActivity { } private void selectFragment(int item) { + this.fragmentState = item; // Handle navigation view item clicks here. try { boolean isLoggedIn = LoginService.isLoggedIn(); @@ -149,4 +182,10 @@ public class MainActivity extends AppCompatActivity { } } } + + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + savedInstanceState.putInt("selected fragment", this.fragmentState); + super.onSaveInstanceState(savedInstanceState); + } } diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/MainFragment.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/MainFragment.java index e907ce7..a4094a5 100644 --- a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/MainFragment.java +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/MainFragment.java @@ -1,8 +1,10 @@ package de.hwr_berlin.it14.postgrachelor; +import android.content.Intent; import android.os.Bundle; import android.app.Fragment; import android.support.v4.content.ContextCompat; +import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.GridLayout; import android.util.Log; import android.view.LayoutInflater; @@ -12,6 +14,8 @@ import android.widget.ImageButton; import android.widget.ProgressBar; import android.widget.TextView; +import org.json.JSONObject; + import java.util.Iterator; import java.util.Locale; @@ -22,6 +26,7 @@ import de.hwr_berlin.it14.postgrachelor.Services.HighscoreService; import de.hwr_berlin.it14.postgrachelor.Services.LoginService; import de.hwr_berlin.it14.postgrachelor.Types.Highscores; import de.hwr_berlin.it14.postgrachelor.Types.HighscoresCategories; +import de.hwr_berlin.it14.postgrachelor.Utils.JsonRequestPG; /** * A simple {@link Fragment} subclass. @@ -30,9 +35,11 @@ import de.hwr_berlin.it14.postgrachelor.Types.HighscoresCategories; */ public class MainFragment extends Fragment { public static final String NAME = "MAIN_FRAGMENT"; + private boolean listenersRegistered; public MainFragment() { // Required empty public constructor + this.listenersRegistered = false; } /** @@ -42,6 +49,7 @@ public class MainFragment extends Fragment { * @return A new instance of fragment MainFragment. */ public static MainFragment newInstance() { + Log.d(NAME, "newInstance"); MainFragment fragment = new MainFragment(); Bundle args = new Bundle(); fragment.setArguments(args); @@ -51,17 +59,29 @@ public class MainFragment extends Fragment { @Override public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) { + Log.d(NAME, "onCreateView "+this.listenersRegistered); final View view = inflater.inflate(R.layout.fragment_main, container, false); - + final View.OnClickListener categoryClick= new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(getActivity(), HighscoreActivity.class); + intent.putExtra("CategoryID", v.getTag(R.id.category_id).toString()); + intent.putExtra("CategoryName", v.getTag(R.id.category_name).toString()); + intent.putExtra("CategoryCount", v.getTag(R.id.category_count).toString()); + startActivity(intent); + } + }; LoginService.addLoginEventListener(NAME, new LoginService.OnLoginEventListener() { @Override public void onLoginEvent(String name, String uid) { TextView textView = (TextView) view.findViewById(R.id.fragment_main_status).findViewById(R.id.fragment_user_name); textView.setText(name); - Log.d(NAME, "onLogin"); + Log.d(NAME, "onLogin", new Throwable()); } - @Override public void onLogoutEvent(int status, String message) {} + @Override + public void onLogoutEvent(int status, String message) { + } }); HighscoreService.addHighscoreUpdateEventListener(new HighscoreService.OnHighscoreUpdateEventListener() { @Override @@ -78,7 +98,7 @@ public class MainFragment extends Fragment { gridLayoutCategories.removeAllViews(); - if (scores==null) { + if (scores == null) { userStatusTextViewScore.setText("0"); userStatusProgressBar.setMax(1); userStatusProgressBar.setProgress(0); @@ -98,9 +118,14 @@ public class MainFragment extends Fragment { ProgressBar catProgress; TextView textView; - while(iterator.hasNext()) { + while (iterator.hasNext()) { HighscoresCategories category = iterator.next(); categoryView = inflater.inflate(R.layout.fragment_main_category, gridLayoutCategories, false); + categoryView.setTag(R.id.category_id, category.getId()); + categoryView.setTag(R.id.category_name, category.getName()); + // TODO automated count + categoryView.setTag(R.id.category_count, scores.getAll()); + categoryView.setOnClickListener(categoryClick); textView = (TextView) categoryView.findViewById(R.id.textViewCategory); textView.setText(category.getName()); @@ -108,8 +133,10 @@ public class MainFragment extends Fragment { textView.setText(String.format(Locale.getDefault(), "%1$d", category.getScore())); catProgress = (ProgressBar) categoryView.findViewById(R.id.progressBarCategory); - catProgress.setProgress(scores.getAll()-category.getPlace()+1); + Log.d(NAME, "all: " + scores.getAll() + " - place: " + category.getPlace() + " - prog: " + (scores.getAll() - category.getPlace() + 1)); + catProgress.setProgress(0); catProgress.setMax(scores.getAll()); + catProgress.setProgress(scores.getAll() - category.getPlace() + 1); gridLayoutCategories.addView(categoryView); param = new GridLayout.LayoutParams(GridLayout.spec(GridLayout.UNDEFINED, 1f), GridLayout.spec(GridLayout.UNDEFINED, 1f)); @@ -119,7 +146,11 @@ public class MainFragment extends Fragment { userStatusTextViewScore.setText(String.format(Locale.getDefault(), "%1$d", scores.getScore())); userStatusProgressBar.setMax(scores.getAll()); - userStatusProgressBar.setProgress(scores.getAll()-scores.getPlace()+1); + userStatusProgressBar.setProgress(scores.getAll() - scores.getPlace() + 1); + userStatusProgressBar.setTag(R.id.category_id, -1); + userStatusProgressBar.setTag(R.id.category_name, view.getResources().getString(R.string.app_name)); + userStatusProgressBar.setTag(R.id.category_count, scores.getAll()); + userStatusProgressBar.setOnClickListener(categoryClick); } } }); @@ -142,6 +173,7 @@ public class MainFragment extends Fragment { } } }); + this.listenersRegistered = true; // Inflate the layout for this fragment View fragmentMainGameView = view.findViewById(R.id.fragment_main_game); @@ -162,6 +194,46 @@ public class MainFragment extends Fragment { } }); + + + + + + // Lookup the swipe container view + final SwipeRefreshLayout swipeContainer = (SwipeRefreshLayout) view.findViewById(R.id.swipeContainer); + // Setup refresh listener which triggers new data loading + swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + try { + HighscoreService.updateHighscores(new JsonRequestPG.AsyncResponse() { + @Override + public void processFinish(JSONObject data) { + swipeContainer.setRefreshing(false); + } + + @Override + public void processError(int status, String message) { + + } + }); + } catch (NotInstantiatedException ignored) { + } catch (NotLoggedInException e) { + try { + LoginService.setLogout(15999, "Not logged in"); + } catch (NotInstantiatedException ignored) { + } + } + } + }); + // Configure the refreshing colors + swipeContainer.setColorSchemeResources(android.R.color.holo_blue_bright, + android.R.color.holo_green_light, + android.R.color.holo_orange_light, + android.R.color.holo_red_light); + + + return view; } diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/QuestionFragment.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/QuestionFragment.java index 29d5f5c..7c40fb4 100644 --- a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/QuestionFragment.java +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/QuestionFragment.java @@ -7,6 +7,9 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; import android.widget.Button; import android.widget.TextView; @@ -20,6 +23,7 @@ import de.hwr_berlin.it14.postgrachelor.Types.Question; import de.hwr_berlin.it14.postgrachelor.Types.QuestionResult; import de.hwr_berlin.it14.postgrachelor.Types.Timings; import de.hwr_berlin.it14.postgrachelor.Utils.Conversion; +import de.hwr_berlin.it14.postgrachelor.Utils.ReverseInterpolator; /** @@ -50,7 +54,10 @@ public class QuestionFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + Log.d(NAME, "onCreateView"); final View view = inflater.inflate(R.layout.fragment_question, container, false); + View layout = view.findViewById(R.id.layout_fragment_question); + final TextView questionTitleView = (TextView) view.findViewById(R.id.questionTitle); final TextView questionCategoryView = (TextView) view.findViewById(R.id.questionCategory); @@ -65,13 +72,30 @@ public class QuestionFragment extends Fragment { (Button) view.findViewById(R.id.questionAnswer3) }; // Inflate the layout for this fragment - + layout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (GameService.isNextNeeded()) + try { + GameService.runNext(); + } catch (NotInstantiatedException e) { + e.printStackTrace(); + } + } + }); for (int i = 0; i < 4; i++) { questionAnswerViews[i].setTag(i); questionAnswerViews[i].setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + if (GameService.isNextNeeded()) { + try { + GameService.runNext(); + } catch (NotInstantiatedException e) { + e.printStackTrace(); + } + } else { try { if (GameService.getState() != GameService.States.ON_HOLD_RESULT) GameService.answer((int) v.getTag()); @@ -79,76 +103,83 @@ public class QuestionFragment extends Fragment { e.printStackTrace(); } } + } }); } GameService.addResultEventListener(NAME, new GameService.OnResultEventListener() { @Override public void onResultEvent(QuestionResult result) { - Log.d(NAME, "onResultEvent - result: " + result); - if (result != null) { - int colorBgClicked = ContextCompat.getColor(getActivity().getApplicationContext(), android.R.color.holo_red_dark); - int colorBg = ContextCompat.getColor(getActivity().getApplicationContext(), android.R.color.holo_green_dark); - int colorText = ContextCompat.getColor(getActivity().getApplicationContext(), android.R.color.black); - int answerID; + Log.d(NAME, "onResultEvent - result: " + result); + if (result != null) { + int colorBgClicked = ContextCompat.getColor(getActivity().getApplicationContext(), android.R.color.holo_red_dark); + int colorBg = ContextCompat.getColor(getActivity().getApplicationContext(), android.R.color.holo_green_dark); + int colorText = ContextCompat.getColor(getActivity().getApplicationContext(), android.R.color.black); + int answerID; - try { - answerID = GameService.getAnswer(); - } catch (NotInstantiatedException e) { - answerID = 0; - e.printStackTrace(); - } - Log.d(NAME, "onResultEvent - answerID: " + answerID); - - questionAnswerViews[answerID].setBackgroundColor(colorBgClicked); - questionAnswerViews[result.getCorrectPos()].setBackgroundColor(colorBg); - questionAnswerViews[result.getCorrectPos()].setTextColor(colorText); - - totalView.setText(Conversion.intToStr(result.getTotal())); - scoreView.setText(Conversion.intToStr(result.getScore())); + try { + answerID = GameService.getAnswer(); + } catch (NotInstantiatedException e) { + answerID = 0; + e.printStackTrace(); } + Log.d(NAME, "onResultEvent - answerID: " + answerID); + + questionAnswerViews[answerID].setBackgroundColor(colorBgClicked); + questionAnswerViews[result.getCorrectPos()].setBackgroundColor(colorBg); + questionAnswerViews[result.getCorrectPos()].setTextColor(colorText); + + totalView.setText(Conversion.intToStr(result.getTotal())); + scoreView.setText(Conversion.intToStr(result.getScore())); + + if (result.isCorrect()) { + Animation animation = AnimationUtils.loadAnimation(getActivity().getApplicationContext(), R.anim.scale_up); + animation.setInterpolator(new ReverseInterpolator(new AccelerateInterpolator())); + totalView.startAnimation(animation); + } + } } }); GameService.addNextQuestionEventListener(NAME, new GameService.OnNextQuestionEventListener() { @Override public void onNextQuestionEvent(Question question) { + for (int i = 0; i < 4; i++) { + questionAnswerViews[i].setBackgroundColor( + ContextCompat.getColor(view.getContext(), R.color.colorPrimary) + ); + questionAnswerViews[i].setTextColor( + ContextCompat.getColor(view.getContext(), android.R.color.white) + ); + } + if (question != null) { + questionTitleView.setText(question.getQuestion()); + questionCategoryView.setText(view.getContext().getResources().getString(R.string.category, question.getCategory())); for (int i = 0; i < 4; i++) { - questionAnswerViews[i].setBackgroundColor( - ContextCompat.getColor(view.getContext(), R.color.colorPrimary) - ); - questionAnswerViews[i].setTextColor( - ContextCompat.getColor(view.getContext(), android.R.color.white) - ); + questionAnswerViews[i].setText(question.getAnswers()[i]); } - if (question != null) { - questionTitleView.setText(question.getQuestion()); - questionCategoryView.setText(view.getContext().getResources().getString(R.string.category, question.getCategory())); - for (int i = 0; i < 4; i++) { - questionAnswerViews[i].setText(question.getAnswers()[i]); - } - } else { - questionTitleView.setText(""); - questionCategoryView.setText(R.string.no_question_available); - for (int i = 0; i < 4; i++) { - questionAnswerViews[i].setText(""); - } + } else { + questionTitleView.setText(""); + questionCategoryView.setText(R.string.no_question_available); + for (int i = 0; i < 4; i++) { + questionAnswerViews[i].setText(""); } } + } }); GameService.addTickEventListener(NAME, new GameService.OnTickEventListener() { @Override public void onTickEvent(Timings timings) { - if (timings != null) { - timeView.setText(Conversion.millisToTime(timings.getTimeDiff())); - scoreView.setText(String.format(Locale.getDefault(), "%1d", timings.getScore())); - } + if (timings != null) { + timeView.setText(Conversion.millisToTime(timings.getTimeDiff())); + scoreView.setText(String.format(Locale.getDefault(), "%1d", timings.getScore())); + } } }); GameService.addGameStateChangeEventListener(NAME, new GameService.OnGameStateChangeEventListener() { @Override public void onGameStateChangeEvent(int previous, int state) { - Log.d(NAME, Conversion.intToStr(previous, 5)+Conversion.intToStr(state,5)); - if (previous != GameService.States.ON_HOLD_RESULT && state == GameService.States.RUNNING) - totalView.setText(R.string._0); + Log.d(NAME, Conversion.intToStr(previous, 5)+Conversion.intToStr(state,5)); + if (previous != GameService.States.ON_HOLD_RESULT && state == GameService.States.RUNNING) + totalView.setText(R.string._0); } }); return view; diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Services/GameService.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Services/GameService.java index 6692901..3dc7744 100644 --- a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Services/GameService.java +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Services/GameService.java @@ -6,8 +6,10 @@ import android.content.SharedPreferences; import android.util.Log; import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; +import java.util.ArrayList; import java.util.HashMap; import java.util.Timer; import java.util.TimerTask; @@ -31,12 +33,14 @@ public class GameService { private static final int GAME_TICK_INTERVAL = 100; private static final int NEXT_QUESTION_DELAY = 1250; private static final int QUESTION_COUNT = 10; + private static final String NAME = "SERVICE_GAME"; private static long startTime; private static long endTime; private static int answer; private static Timer timer; + private static JSONObject data = null; public static final class States { private States() {} @@ -58,7 +62,7 @@ public class GameService { private static final HashMap resultEventListeners = new HashMap<>(); private static final HashMap gameEndEventListeners = new HashMap<>(); private static final HashMap gameTickEventListeners = new HashMap<>(); - private static int state = States.END; + private static int state = States.UNINITIALIZED; private static Question question = null; private static QuestionResult result = null; private static GameScores scores = null; @@ -89,6 +93,11 @@ public class GameService { GameService.activity = activity; GameService.settings = activity.getSharedPreferences(GameService.PREFS_NAME, 0); GameService.initialized = true; + try { + GameService.data = GameService.getNeededNext(); + } catch (NotInstantiatedException e) { + e.printStackTrace(); + } emitNextQuestionEvent(); emitGameEndEvent(); @@ -156,8 +165,6 @@ public class GameService { @SuppressWarnings("SameParameterValue") public static void addTickEventListener(String key, OnTickEventListener onTickEventListener) { gameTickEventListeners.put(key, onTickEventListener); - if (GameService.initialized) - onTickEventListener.onTickEvent(GameService.getTimingsSave()); } private static Timings getTimingsSave() { @@ -373,6 +380,8 @@ public class GameService { } public static void answer(int id) throws NotInstantiatedException, NotLoggedInException, NoCurrentQuestionException { + if (GameService.isNextNeeded()) + throw new IllegalStateException(); if (!GameService.initialized) throw new NotInstantiatedException(); final int state = GameService.getState(); @@ -384,10 +393,10 @@ public class GameService { time = end - start; id = GameService.getAnswer(id); } else if (state == States.RUNNING) { + GameService.setState(States.ON_HOLD_LOADING); long end = System.currentTimeMillis(); long start = GameService.getStartTime(); GameService.setEndTime(end); - GameService.setState(States.ON_HOLD_LOADING); time = end - start; GameService.setAnswer(id); } else { @@ -412,26 +421,9 @@ public class GameService { data_result.optInt("correctPos", 0), data_result.optInt("total", 0) ); - GameService.setStateSave(States.ON_HOLD_RESULT); GameService.setResultSave(result); - - new android.os.Handler().postDelayed(new Runnable() { - @Override - public void run() { - if (data.has("next")) { - JSONObject data_next = data.optJSONObject("next"); - GameService.setQuestionSave(GameService.parseQuestion(data_next)); - GameService.setStartTimeSave(System.currentTimeMillis()); - GameService.setStateSave(States.RUNNING); - } else { - JSONObject data_end = data.optJSONObject("end"); - GameService.setScoresSave(GameService.parseScores(data_end)); - GameService.setStateSave(States.END); - GameService.unsetStartTimeSave(); - GameService.unsetEndTimeSave(); - } - } - }, GameService.NEXT_QUESTION_DELAY); + GameService.setNeededNextSave(data); + GameService.setStateSave(States.ON_HOLD_RESULT); } @Override @@ -452,6 +444,7 @@ public class GameService { if (!GameService.initialized) throw new NotInstantiatedException(); + GameService.setNeededNext(null); HashMap params = new HashMap<>(); String uid; uid = LoginService.getLoginUID(); @@ -487,6 +480,112 @@ public class GameService { requester.execute(); } + private static void setNeededNext(JSONObject data) throws NotInstantiatedException { + GameService.data = data; + if (!GameService.initialized) + throw new NotInstantiatedException(); + SharedPreferences.Editor editor = GameService.settings.edit(); + if (data!=null && data.has("next")) { + data = data.optJSONObject("next"); + JSONArray array = data.optJSONArray("answers"); + editor.putString("nextCategoryName", data.optString("categoryName", "")); + editor.putInt("nextCategoryID", data.optInt("categoryID", 0)); + editor.putString("nextQuestion", data.optString("question", "")); + editor.putString("nextAnswers0", array.optString(0, "")); + editor.putString("nextAnswers1", array.optString(1, "")); + editor.putString("nextAnswers2", array.optString(2, "")); + editor.putString("nextAnswers3", array.optString(3, "")); + } else { + editor.remove("nextCategoryName"); + editor.remove("nextCategoryID"); + editor.remove("nextQuestion"); + editor.remove("nextAnswers0"); + editor.remove("nextAnswers1"); + editor.remove("nextAnswers2"); + editor.remove("nextAnswers3"); + } + if (data!=null && data.has("end")) { + data = data.optJSONObject("end"); + editor.putInt("endScore", data.optInt("score", 0)); + editor.putLong("endTime", data.optLong("time", 0)); + } else { + editor.remove("endScore"); + editor.remove("endTime"); + } + editor.apply(); + } + + private static void setNeededNextSave(JSONObject data) { + try { + GameService.setNeededNext(data); + } catch (NotInstantiatedException e) { + e.printStackTrace(); + } + } + + private static JSONObject getNeededNext() throws NotInstantiatedException { + if (GameService.data == null) { + if (!GameService.initialized) + throw new NotInstantiatedException(); + JSONObject data; + if (GameService.settings.contains("nextCategoryName")) { + data = new JSONObject(); + try { + data.put("categoryName", GameService.settings.getString("nextCategoryName", "")); + data.put("categoryID", GameService.settings.getInt("nextCategoryID", 0)); + data.put("question", GameService.settings.getString("nextQuestion", "")); + ArrayList list = new ArrayList<>(); + list.add(GameService.settings.getString("nextAnswers0", "")); + list.add(GameService.settings.getString("nextAnswers1", "")); + list.add(GameService.settings.getString("nextAnswers2", "")); + list.add(GameService.settings.getString("nextAnswers3", "")); + data.put("answers", new JSONArray(list)); + data = (new JSONObject()).put("next", data); + } catch (JSONException e) { + data = null; + e.printStackTrace(); + } + } else if (GameService.settings.contains("endScore")) { + data = new JSONObject(); + try { + data.put("score", GameService.settings.getInt("endScore", 0)); + data.put("time", GameService.settings.getLong("endTime", 0)); + data = (new JSONObject()).put("end", data); + } catch (JSONException e) { + data = null; + e.printStackTrace(); + } + } else { + data = null; + } + GameService.data = data; + } + return GameService.data; + } + + public static boolean isNextNeeded() { + return GameService.data != null; + } + + public static void runNext() throws IllegalStateException, NotInstantiatedException { + JSONObject data = GameService.getNeededNext(); + if (data == null) + throw new IllegalStateException(); + if (data.has("next")) { + JSONObject data_next = data.optJSONObject("next"); + GameService.setQuestionSave(GameService.parseQuestion(data_next)); + GameService.setStartTimeSave(System.currentTimeMillis()); + GameService.setStateSave(States.RUNNING); + } else { + JSONObject data_end = data.optJSONObject("end"); + GameService.setScoresSave(GameService.parseScores(data_end)); + GameService.setStateSave(States.END); + GameService.unsetStartTimeSave(); + GameService.unsetEndTimeSave(); + } + GameService.setNeededNext(null); + } + private static void setQuestion(Question question) throws NotInstantiatedException { if (!initialized) throw new NotInstantiatedException(); @@ -528,8 +627,9 @@ public class GameService { int previous = GameService.getState(); GameService.state = state; SharedPreferences.Editor editor = GameService.settings.edit(); - if (state==States.UNINITIALIZED) + if (state!=States.UNINITIALIZED) { editor.putInt("gameState", state); + } else editor.remove("gameState"); editor.apply(); diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Services/HighscoreService.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Services/HighscoreService.java index 5b8564b..b69d58b 100644 --- a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Services/HighscoreService.java +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Services/HighscoreService.java @@ -15,6 +15,8 @@ import de.hwr_berlin.it14.postgrachelor.Exceptions.NotInstantiatedException; import de.hwr_berlin.it14.postgrachelor.Exceptions.NotLoggedInException; import de.hwr_berlin.it14.postgrachelor.Types.GameScores; import de.hwr_berlin.it14.postgrachelor.Types.Highscores; +import de.hwr_berlin.it14.postgrachelor.Types.HighscoresUser; +import de.hwr_berlin.it14.postgrachelor.Utils.Conversion; import de.hwr_berlin.it14.postgrachelor.Utils.JsonRequestPG; /** @@ -24,6 +26,7 @@ import de.hwr_berlin.it14.postgrachelor.Utils.JsonRequestPG; public class HighscoreService { private static final String NAME = "HighscoreService"; + private static final long MIN_REFRESH_RATE = 1000; //private static final String PREFS_NAME = "PrefsHighscore"; //private static SharedPreferences settings = null; private static Highscores latestScores = null; @@ -31,6 +34,7 @@ public class HighscoreService { @SuppressLint("StaticFieldLeak") private static Activity activity = null; private static final ArrayList highscoreUpdateEventListeners = new ArrayList<>(); + private static long lastUpdate = 0; public interface OnHighscoreUpdateEventListener { void onHighscoreUpdateEvent(Highscores scores); @@ -51,34 +55,6 @@ public class HighscoreService { //settings = activity.getSharedPreferences(PREFS_NAME, 0); HighscoreService.activity = activity; instantiated = true; - LoginService.addLoginEventListener(NAME, new LoginService.OnLoginEventListener() { - @Override - public void onLoginEvent(String name, String uid) { - try { - HighscoreService.updateHighscores(); - } catch (NotInstantiatedException | NotLoggedInException e) { - e.printStackTrace(); - HighscoreService.setLatestScores(null); - } - } - - @Override - public void onLogoutEvent(int status, String message) { - HighscoreService.setLatestScores(null); - } - }); - - GameService.addGameEndEventListener(NAME, new GameService.OnGameEndEventListener() { - @Override - public void onGameEndEvent(GameScores scores) { - try { - HighscoreService.updateHighscores(); - } catch (NotInstantiatedException | NotLoggedInException e) { - e.printStackTrace(); - HighscoreService.setLatestScores(null); - } - } - }); } public static boolean available() { @@ -94,7 +70,14 @@ public class HighscoreService { emitHighscoreUpdateEvent(); } - private static void updateHighscores() throws NotInstantiatedException, NotLoggedInException { + public static void updateHighscores() throws NotInstantiatedException, NotLoggedInException { + HighscoreService.updateHighscores(null); + } + + public static void updateHighscores(final JsonRequestPG.AsyncResponse asyncResponse) throws NotInstantiatedException, NotLoggedInException { + //if (lastUpdate >= System.currentTimeMillis()-MIN_REFRESH_RATE) + // return; + //lastUpdate = System.currentTimeMillis(); if (!instantiated) throw new NotInstantiatedException(); @@ -105,9 +88,6 @@ public class HighscoreService { JsonRequestPG requester = new JsonRequestPG("highscores.php", params, activity, new JsonRequestPG.AsyncResponse() { @Override public void processFinish(JSONObject output) { - Log.d("Activity fragment", "output"); - Log.d("Activity fragment", output.toString()); - // never reached if not instantiated Highscores result = new Highscores( output.optInt("score", 0), @@ -132,6 +112,10 @@ public class HighscoreService { } } setLatestScores(result); + + if (asyncResponse != null) { + asyncResponse.processFinish(output); + } } @Override @@ -144,8 +128,57 @@ public class HighscoreService { e.printStackTrace(); } } + + if (asyncResponse != null) { + asyncResponse.processError(status, message); + } } }); requester.execute(); } + + public static ArrayList getHighscoreDetailsSync(final int limit, int offset, int category, final JsonRequestPG.AsyncResponse asyncResponse) { + HashMap params = new HashMap<>(); + if (limit >= 0) + params.put("limit", Conversion.intToStr(limit)); + if (offset >= 0) + params.put("offset", Conversion.intToStr(offset)); + if (category >= 0) + params.put("category", Conversion.intToStr(category)); + final ArrayList highscoresUsers = new ArrayList<>(); + JsonRequestPG requester = new JsonRequestPG("allhighscores.php", params, activity, new JsonRequestPG.AsyncResponse() { + @Override + public void processFinish(JSONObject output) { + if (output != null) { + JSONArray array = output.optJSONArray("array"); + if (array != null) { + for (int i = 0; i < array.length(); i++) { + JSONObject objectItem = array.optJSONObject(i); + if (objectItem != null) { + highscoresUsers.add(new HighscoresUser( + objectItem.optString("name", "A Random User"), + objectItem.optInt("score"), + objectItem.optInt("place") + )); + } else { + highscoresUsers.add(null); + } + } + } + } + if (asyncResponse != null) { + asyncResponse.processFinish(output); + } + } + + @Override + public void processError(int status, String message) { + if (asyncResponse != null) { + asyncResponse.processError(status, message); + } + } + }); + requester.executeSync(); + return highscoresUsers; + } } diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Services/LoginService.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Services/LoginService.java index 3835ff6..25c4c6a 100644 --- a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Services/LoginService.java +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Services/LoginService.java @@ -40,7 +40,7 @@ public class LoginService { e.printStackTrace(); } } else { - onLoginEventListener.onLogoutEvent(-6, null); + //onLoginEventListener.onLogoutEvent(-6, null); } } @@ -118,7 +118,7 @@ public class LoginService { emitLoginEvent(name, uid); } - static void setLogout(int status, String message) throws NotInstantiatedException { + public static void setLogout(int status, String message) throws NotInstantiatedException { if (!instantiated) throw new NotInstantiatedException(); SharedPreferences.Editor editor = settings.edit(); diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Types/HighscoresUser.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Types/HighscoresUser.java new file mode 100644 index 0000000..ad5ff9a --- /dev/null +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Types/HighscoresUser.java @@ -0,0 +1,37 @@ +package de.hwr_berlin.it14.postgrachelor.Types; + +/** + * Created by Sebastian on 11.04.2017. + */ + +public class HighscoresUser extends Requestable { + private final String name; + private final int score; + private final int place; + + public HighscoresUser(String name, int score, int place) { + this.name = name; + this.score = score; + this.place = place; + this.unrequested(); + } + + public HighscoresUser() { + super(); + this.name = ""; + this.score = 0; + this.place = 0; + } + + public String getName() { + return name; + } + + public int getScore() { + return score; + } + + public int getPlace() { + return place; + } +} diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Types/Requestable.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Types/Requestable.java new file mode 100644 index 0000000..c74d38e --- /dev/null +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Types/Requestable.java @@ -0,0 +1,25 @@ +package de.hwr_berlin.it14.postgrachelor.Types; + +/** + * Created by Sebastian on 12.04.2017. + */ + +public class Requestable { + private long requested; + + public Requestable() { + this.requested(); + } + + public boolean isRequested() { + return this.requested != 0; + } + + protected void unrequested() { + this.requested = 0; + } + + protected void requested() { + this.requested = System.currentTimeMillis(); + } +} diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/AsyncAdapter.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/AsyncAdapter.java new file mode 100644 index 0000000..04afe89 --- /dev/null +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/AsyncAdapter.java @@ -0,0 +1,151 @@ +package de.hwr_berlin.it14.postgrachelor.Utils; + +import android.os.AsyncTask; +import android.test.suitebuilder.annotation.Suppress; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; + +import java.util.ArrayList; + +import de.hwr_berlin.it14.postgrachelor.Types.Requestable; + +/** + * Created by Sebastian on 10.04.2017. + */ + +public abstract class AsyncAdapter extends BaseAdapter { + + private int count; + private ArrayList items; + + private AsyncAdapter() {} + + public AsyncAdapter(int count) { + super(); + items = new ArrayList<>(); + this.setCount(count); + } + + @Override + public int getCount() { + return this.count; + } + + @Override + public Integer getItem(int position) { + return null; + } + + @Override + public long getItemId(int position) { + return 0; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) + convertView = this.inflateView(position, parent); + convertView = this.clearView(position, convertView); + this.loadView(position, convertView, parent); + return convertView; + } + + @SuppressWarnings("unchecked") + private void loadView(int position, View convertView, ViewGroup parent) { + if (position >= this.items.size() || this.items.get(position) == null) { + AsyncRequest request = new AsyncRequest(position, convertView); + request.execute(); + } else if (!this.items.get(position).isRequested()) { + this.fillView((T) this.items.get(position), position, convertView); + } + } + + abstract void fillView(T item, int position, View convertView); + + abstract View inflateView(int position, ViewGroup parent); + + abstract View clearView(int position, View convertView); + + abstract ListSequence getAsyncListSequence(int position); + + private void setCount(int count) { + this.count = count; + } + + protected abstract int getRequestedLength(int position); + + + + + class AsyncRequest extends AsyncTask> { + + private final int position; + private View convertView; + + AsyncRequest(int position, View convertView) { + this.position = position; + this.convertView = convertView; + } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + for (int i = items.size(); i < this.position; i++) { + items.add(null); + } + for (int i = this.position; i < this.position+getRequestedLength(this.position); i++) { + if (i < items.size()) + items.set(i, new Requestable()); + else + items.add(new Requestable()); + } + } + + + @Override + protected ListSequence doInBackground(Void... arg0) { + return getAsyncListSequence(position); + } + + @Override + @SuppressWarnings("unchecked") + protected void onPostExecute(ListSequence result) { + super.onPostExecute(result); + int start = result.getStart(); + ArrayList list = result.getItems(); + for (int i = items.size(); i < start; i++) { + items.add(null); + } + while (list.size() > 0) { + if (start < items.size()) + items.set(start, list.remove(0)); + else + items.add(list.remove(0)); + start++; + } + if (position < items.size()) + fillView((T) items.get(position), position, convertView); + notifyDataSetChanged(); + } + } + + class ListSequence { + private final int start; + private final ArrayList items; + + public ListSequence(int start, int end, ArrayList items) { + this.start = start; + this.items = items; + } + + + public int getStart() { + return start; + } + + public ArrayList getItems() { + return items; + } + } +} diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/Conversion.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/Conversion.java index 5a0e8e9..2823dfc 100644 --- a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/Conversion.java +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/Conversion.java @@ -34,4 +34,12 @@ public class Conversion { private static String intToStr(int i, int padding, char padChar) { return Conversion.intToStr(i, padding).replace(' ', padChar); } + + public static int strToInt(String string, int defValue) { + try{ + return Integer.parseInt(string); + }catch(NumberFormatException e){ + return defValue; + } + } } diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/HighscoreAdapter.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/HighscoreAdapter.java new file mode 100644 index 0000000..66af46d --- /dev/null +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/HighscoreAdapter.java @@ -0,0 +1,82 @@ +package de.hwr_berlin.it14.postgrachelor.Utils; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.ArrayList; + +import de.hwr_berlin.it14.postgrachelor.R; +import de.hwr_berlin.it14.postgrachelor.Services.HighscoreService; +import de.hwr_berlin.it14.postgrachelor.Types.HighscoresUser; + +/** + * Created by Sebastian on 11.04.2017. + */ + +public class HighscoreAdapter extends AsyncAdapter { + private Context context; + private int category; + + public HighscoreAdapter(int count, int category, Context context) { + super(count); + this.category = category; + this.context = context; + } + + @Override + void fillView(HighscoresUser item, int position, View convertView) { + if (item == null) { + return; + } + TextView userNameView = (TextView) convertView.findViewById(R.id.tvName); + TextView userPlaceView = (TextView) convertView.findViewById(R.id.tvPlace); + TextView userScoreView = (TextView) convertView.findViewById(R.id.tvScore); + if (userNameView != null) { + userNameView.setText(item.getName()); + } + if (userPlaceView != null) { + userPlaceView.setText(convertView.getContext().getResources().getString(R.string.place, Conversion.intToStr(item.getPlace()))); + } + if (userScoreView != null) { + userScoreView.setText(Conversion.intToStr(item.getScore())); + } + } + + @Override + View inflateView(int position, ViewGroup parent) { + LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + return inflater.inflate(R.layout.adapter_highscore_details, parent, false); + } + + @Override + View clearView(int position, View convertView) { + TextView userNameView = (TextView) convertView.findViewById(R.id.tvName); + TextView userPlaceView = (TextView) convertView.findViewById(R.id.tvPlace); + TextView userScoreView = (TextView) convertView.findViewById(R.id.tvScore); + if (userNameView != null) { + userNameView.setText(R.string.loading); + } + if (userPlaceView != null) { + userPlaceView.setText(convertView.getContext().getResources().getString(R.string.place, Conversion.intToStr(position+1))); + } + if (userScoreView != null) { + userScoreView.setText(""); + } + return convertView; + } + + @Override + ListSequence getAsyncListSequence(int position) { + int limit = this.getRequestedLength(position); + ArrayList items = HighscoreService.getHighscoreDetailsSync(limit, position, this.category, null); + return new ListSequence<>(position, position+items.size()-1, items); + } + + @Override + protected int getRequestedLength(int position) { + return Math.min(10, getCount()-position); + } +} diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/JsonRequest.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/JsonRequest.java index 9dcc983..2c2fd28 100644 --- a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/JsonRequest.java +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/JsonRequest.java @@ -36,12 +36,18 @@ abstract class JsonRequest extends AsyncTask { this.path = path; this.params = params; this.activity = activity; - Log.d("fragment, JSONRequest", connectionURL+path); + Log.d("JSONRequest create", connectionURL+path); } @SuppressWarnings("SameReturnValue") protected abstract String getConnectionURL(); + public JSONObject executeSync() { + JSONObject result = this.doInBackground(); + Log.d("JSONRequest excecute", result.toString()); + return result; + } + @Override protected void onPreExecute() { super.onPreExecute(); @@ -68,6 +74,7 @@ abstract class JsonRequest extends AsyncTask { if (url == null) return new JSONObject(); try { + Log.d("JSONRequest url", url.toString()); urlConnection = (HttpURLConnection) url.openConnection(); } catch (IOException e) { e.printStackTrace(); diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/JsonRequestPG.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/JsonRequestPG.java index ad47385..28333d1 100644 --- a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/JsonRequestPG.java +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/JsonRequestPG.java @@ -4,8 +4,11 @@ import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; +import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; +import java.util.ArrayList; import java.util.HashMap; /** @@ -15,7 +18,7 @@ import java.util.HashMap; public class JsonRequestPG extends JsonRequest { - private final AsyncResponse delegate; + private final ArrayList delegates; public interface AsyncResponse { void processFinish(JSONObject data); @@ -24,7 +27,53 @@ public class JsonRequestPG extends JsonRequest { public JsonRequestPG(String path, HashMap params, Activity activity, AsyncResponse delegate) { super(path, params, activity); - this.delegate = delegate; + this.delegates = new ArrayList<>(); + this.delegates.add(delegate); + } + + private void processError(int status, String message) { + for (AsyncResponse delegate: delegates) { + delegate.processError(status, message); + } + } + + private void processFinish(JSONObject data) { + for (AsyncResponse delegate: delegates) { + delegate.processFinish(data); + } + } + + public JSONObject executeSync() { + JSONObject result = super.executeSync(); + if (result == null) { + this.processError(-1, "Internal error occurred!"); + return null; + } + JSONObject meta = result.optJSONObject("meta"); + if (meta==null) { + this.processError(-2, "Invalid JSON: Meta tag not found!"); + return null; + } + int status = meta.optInt("status", -3); + String message = meta.optString("message", ""); + if (status != 0) { + this.processError(status, message); + return null; + } + JSONArray array = result.optJSONArray("data"); + JSONObject data; + if (array != null) { + data = new JSONObject(); + try { + data.put("array", array); + } catch (JSONException e) { + e.printStackTrace(); + } + } else { + data = result.optJSONObject("data"); + } + this.processFinish(data); + return data; } @Override @@ -36,12 +85,12 @@ public class JsonRequestPG extends JsonRequest { protected void onPostExecute(JSONObject result) { super.onPostExecute(result); if (result == null) { - delegate.processError(-1, "Internal error occurred!"); + this.processError(-1, "Internal error occurred!"); return; } JSONObject meta = result.optJSONObject("meta"); if (meta==null) { - delegate.processError(-2, "Invalid JSON: Meta tag not found!"); + this.processError(-2, "Invalid JSON: Meta tag not found!"); return; } int status = meta.optInt("status", -3); @@ -57,10 +106,21 @@ public class JsonRequestPG extends JsonRequest { }) .setIcon(android.R.drawable.ic_dialog_alert) .show(); - delegate.processError(status, message); + this.processError(status, message); return; } - JSONObject data = result.optJSONObject("data"); - delegate.processFinish(data); + JSONArray array = result.optJSONArray("data"); + JSONObject data; + if (array != null) { + data = new JSONObject(); + try { + data.put("array", array); + } catch (JSONException e) { + e.printStackTrace(); + } + } else { + data = result.optJSONObject("data"); + } + this.processFinish(data); } } diff --git a/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/ReverseInterpolator.java b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/ReverseInterpolator.java new file mode 100644 index 0000000..501fc30 --- /dev/null +++ b/app/src/main/java/de/hwr_berlin/it14/postgrachelor/Utils/ReverseInterpolator.java @@ -0,0 +1,35 @@ +package de.hwr_berlin.it14.postgrachelor.Utils; + +import android.view.animation.Interpolator; +import android.view.animation.LinearInterpolator; + +/** + * Created by Sebastian on 08.04.2017. + */ + +public class ReverseInterpolator implements Interpolator { + private final Interpolator delegate; + + public ReverseInterpolator(Interpolator delegate){ + this.delegate = delegate; + } + + public ReverseInterpolator(){ + this(new LinearInterpolator()); + } + + @Override + public float getInterpolation(float input) { + return this.delegate.getInterpolation(this.reverseInput(input)); + } + + /** + * Map value so 0-0.5 = 0-1 and 0.5-1 = 1-0 + */ + private float reverseInput(float input){ + if(input <= 0.5) + return input*2; + else + return Math.abs(input-1)*2; + } +} diff --git a/app/src/main/res/anim/scale_up.xml b/app/src/main/res/anim/scale_up.xml new file mode 100644 index 0000000..d98fa56 --- /dev/null +++ b/app/src/main/res/anim/scale_up.xml @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_highscore.xml b/app/src/main/res/layout/activity_highscore.xml new file mode 100644 index 0000000..3e64254 --- /dev/null +++ b/app/src/main/res/layout/activity_highscore.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index c12c1dc..d619782 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -4,8 +4,7 @@ android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" - android:fitsSystemWindows="true" - tools:openDrawer="start"> + android:fitsSystemWindows="true"> + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index 044045f..e4f6f7b 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -1,11 +1,15 @@ - + + + + - \ No newline at end of file + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main_category.xml b/app/src/main/res/layout/fragment_main_category.xml index c114e6a..a203150 100644 --- a/app/src/main/res/layout/fragment_main_category.xml +++ b/app/src/main/res/layout/fragment_main_category.xml @@ -17,19 +17,13 @@ + android:layout_alignParentBottom="true"/> @@ -27,7 +29,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/_02_15" - android:layout_marginBottom="330sp" + android:layout_marginBottom="320sp" android:textAppearance="@style/TextAppearance.AppCompat.Large" android:layout_alignParentBottom="true" /> @@ -36,7 +38,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/_1337" - android:layout_marginBottom="330sp" + android:layout_marginBottom="320sp" android:textAppearance="@style/TextAppearance.AppCompat.Large" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" @@ -45,7 +47,7 @@ android:id="@+id/questionTotal" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginBottom="330sp" + android:layout_marginBottom="320sp" android:textAppearance="@style/TextAppearance.AppCompat.Large" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 29dc17e..1163449 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -19,4 +19,6 @@ Keine Fragen verfügbar! Spiele ein Spiel! Bitte warten… + Lädt… + %1$s. diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 3ab3e9c..8f4a31d 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,6 +1,8 @@ - #3F51B5 - #303F9F + + #5262BC + + #2B388F #FF4081 diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml new file mode 100644 index 0000000..a08da6c --- /dev/null +++ b/app/src/main/res/values/ids.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bfb5f41..cbbc0ef 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -24,4 +24,6 @@ 0 Play a Game! Please wait… + Loading… + #%1$s diff --git a/build.gradle b/build.gradle index 1ea4bd0..b78a0b8 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.0' + classpath 'com.android.tools.build:gradle:2.3.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files