diff --git a/app/src/androidTest/java/com/ryanwarsaw/coach_erevu/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/ryanwarsaw/coach_erevu/ExampleInstrumentedTest.java index 4e7fdba..034e637 100644 --- a/app/src/androidTest/java/com/ryanwarsaw/coach_erevu/ExampleInstrumentedTest.java +++ b/app/src/androidTest/java/com/ryanwarsaw/coach_erevu/ExampleInstrumentedTest.java @@ -1,13 +1,14 @@ package com.ryanwarsaw.coach_erevu; -import static org.junit.Assert.assertEquals; - import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; +import static org.junit.Assert.assertEquals; + /** * Instrumented test, which will execute on an Android device. * diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8150a2b..7b7fba8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,16 +15,17 @@ android:theme="@style/AppTheme"> - - - + + + + \ No newline at end of file diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/MainActivity.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/MainActivity.java index e9a72c4..4aa03d5 100644 --- a/app/src/main/java/com/ryanwarsaw/coach_erevu/MainActivity.java +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/MainActivity.java @@ -8,19 +8,23 @@ import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Environment; +import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.widget.LinearLayout; import android.widget.ListView; + import com.google.gson.GsonBuilder; -import com.ryanwarsaw.coach_erevu.adapter.MenuAdapter; +import com.ryanwarsaw.coach_erevu.adapter.CategoryAdapter; import com.ryanwarsaw.coach_erevu.logging.LoggingHandler; import com.ryanwarsaw.coach_erevu.model.Curriculum; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; + import lombok.Cleanup; import lombok.Getter; @@ -28,7 +32,6 @@ public class MainActivity extends AppCompatActivity { @Getter public Curriculum curriculum; - private MenuAdapter menuAdapter; private static LoggingHandler loggingHandler; private static String CONTENT_FILENAME = "content.json"; @@ -46,19 +49,11 @@ protected void onCreate(Bundle savedInstanceState) { // Manually update the orientation when initially starting the app. onConfigurationChanged(getResources().getConfiguration()); - // Import the content.json file into memory, log the result. - curriculum = parseContentFile(CONTENT_FILENAME); - - // Create the log file if it doesn't exist, instantiate our logger. - loggingHandler = new LoggingHandler(LOG_FILENAME); - - getLoggingHandler().write(getClass().getSimpleName(), "APP_STARTED", curriculum.getVersion()); - - // Check edge case of the app not having appropriate permissions. - if (curriculum != null) { - // Build the main menu options from the content.json file - menuAdapter = new MenuAdapter(this, curriculum); - ((ListView) findViewById(R.id.menu_options)).setAdapter(menuAdapter); + // Mostly for first-time users, makes sure we have proper permissions before inflating content. + if (!hasPermissions(this, PERMISSIONS)) { + ActivityCompat.requestPermissions(this, PERMISSIONS, 1); + } else { + inflateContentFile(CONTENT_FILENAME); } } @@ -74,13 +69,11 @@ public void onConfigurationChanged(Configuration newConfig) { } @Override - public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { + public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { if (requestCode == 1 && grantResults.length > 0 - && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Successfully received permission approval, finish inflating the main menu. - curriculum = parseContentFile(CONTENT_FILENAME); - menuAdapter = new MenuAdapter(this, curriculum); - ((ListView) findViewById(R.id.menu_options)).setAdapter(menuAdapter); + inflateContentFile(CONTENT_FILENAME); } else { finishAffinity(); // Failed to receive permission approval, kill the application. } @@ -91,29 +84,28 @@ public void onRequestPermissionsResult(int requestCode, String permissions[], in * check the Download/ folder on your Android device for a file with the name provided. If * it is unable to find that file, it will default to the app packaged version. * @param fileName The fully qualified name of the file (including extension). - * @return Curriculum object representation of the content file, or null if an error occurred. */ - private Curriculum parseContentFile(String fileName) { - if (hasPermissions(this, PERMISSIONS)) { - File externalFile = new File(Environment.getExternalStoragePublicDirectory( - Environment.DIRECTORY_DOWNLOADS).getPath() + "/" + fileName); - try { - @Cleanup InputStream inputStream = externalFile.exists() ? - new FileInputStream(externalFile) : getResources().openRawResource(R.raw.content); - @Cleanup ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - - byte[] buffer = new byte[inputStream.available()]; - inputStream.read(buffer); - outputStream.write(buffer); - - return new GsonBuilder().create().fromJson(outputStream.toString(), Curriculum.class); - } catch (IOException e) { - throw new RuntimeException("An error occurred while trying to parse file: " + fileName); - } - } else { - ActivityCompat.requestPermissions(this, PERMISSIONS, 1); + private void inflateContentFile(String fileName) { + File externalFile = new File(Environment.getExternalStoragePublicDirectory( + Environment.DIRECTORY_DOWNLOADS).getPath() + "/" + fileName); + loggingHandler = new LoggingHandler(LOG_FILENAME); + + try { + @Cleanup InputStream inputStream = externalFile.exists() ? + new FileInputStream(externalFile) : getResources().openRawResource(R.raw.content); + @Cleanup ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + byte[] buffer = new byte[inputStream.available()]; + inputStream.read(buffer); + outputStream.write(buffer); + + curriculum = new GsonBuilder().create().fromJson(outputStream.toString(), Curriculum.class); + } catch (IOException e) { + throw new RuntimeException("An error occurred while trying to parse file: " + fileName); } - return null; + + ((ListView) findViewById(R.id.menu_options)).setAdapter(new CategoryAdapter(this, getCurriculum())); + getLoggingHandler().write(getClass().getSimpleName(), "APP_STARTED", getCurriculum().getVersion()); } /** diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/ActionActivity.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/ActionActivity.java index f275c9d..0fe59a1 100644 --- a/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/ActionActivity.java +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/ActionActivity.java @@ -1,53 +1,79 @@ package com.ryanwarsaw.coach_erevu.activity; import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.LayerDrawable; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.TextView; + +import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.ryanwarsaw.coach_erevu.MainActivity; import com.ryanwarsaw.coach_erevu.R; -import com.ryanwarsaw.coach_erevu.model.Week; +import com.ryanwarsaw.coach_erevu.model.Preferences; +import com.ryanwarsaw.coach_erevu.model.Topic; public class ActionActivity extends AppCompatActivity { - private Week week; + private Topic topic; + private Preferences preferences; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_action); - // We use GSON to serialize and deserialize our payload so we - // can handily pass it around activities without problem. - final String payload = getIntent().getStringExtra("payload"); - week = new GsonBuilder().create().fromJson(payload, Week.class); + // GSON is responsible for serializing and de-serializing our payload data + // so that we can pass it between activities using intents without problems. + final Gson gson = new GsonBuilder().create(); + topic = gson.fromJson(getIntent().getStringExtra("topic"), Topic.class); + preferences = gson.fromJson(getIntent().getStringExtra("preferences"), Preferences.class); // Update header text for the current week we're on. - ((TextView) findViewById(R.id.header_text)).setText(week.getTitle()); + ((TextView) findViewById(R.id.header_text)).setText(topic.getTitle()); // Handle when a user interact's with the watch video button. final Button videoButton = findViewById(R.id.watch_video_button); + + // Dynamically change the button background color based on the content file, without changing + // the rest of the drawable element's background(s), or other instances of the drawable. + ((GradientDrawable) ((LayerDrawable) videoButton.getBackground().mutate()) + .findDrawableByLayerId(R.id.button_background)) + .setColor(Color.parseColor(preferences.getVideoButtonColor())); + videoButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { final Intent intent = new Intent(ActionActivity.this, VideoActivity.class); - intent.putExtra("video_name", week.getVideoName()); + intent.putExtra("video_name", topic.getVideoName()); + intent.putExtra("preferences", gson.toJson(preferences)); + MainActivity.getLoggingHandler().write(ActionActivity.this.getClass().getSimpleName(), - "BUTTON_VIDEO_PRESS", week.getVideoName()); + "BUTTON_VIDEO_PRESS", topic.getVideoName()); ActionActivity.this.startActivity(intent); } }); final Button quizButton = findViewById(R.id.take_quiz_button); + + // Dynamically change the button background color based on the content file, without changing + // the rest of the drawable element's background(s), or other instances of the drawable. + ((GradientDrawable) ((LayerDrawable) quizButton.getBackground().mutate()) + .findDrawableByLayerId(R.id.button_background)) + .setColor(Color.parseColor(preferences.getQuizButtonColor())); + quizButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { - if (week.getQuestions().size() > 0) { + if (topic.getQuestions().size() > 0) { final Intent intent = new Intent(ActionActivity.this, QuizActivity.class); - intent.putExtra("payload", payload); + intent.putExtra("topic", gson.toJson(topic)); + intent.putExtra("preferences", gson.toJson(preferences)); + MainActivity.getLoggingHandler().write(ActionActivity.this.getClass().getSimpleName(), - "BUTTON_QUIZ_PRESS", week.getTitle()); + "BUTTON_QUIZ_PRESS", topic.getTitle()); ActionActivity.this.startActivity(intent); } } diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/QuizActivity.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/QuizActivity.java index f06506d..b33b27c 100644 --- a/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/QuizActivity.java +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/QuizActivity.java @@ -12,40 +12,45 @@ import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; + +import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.ryanwarsaw.coach_erevu.MainActivity; import com.ryanwarsaw.coach_erevu.R; import com.ryanwarsaw.coach_erevu.adapter.AnswerAdapter; import com.ryanwarsaw.coach_erevu.fragment.WrongAnswerFragment; +import com.ryanwarsaw.coach_erevu.model.Preferences; import com.ryanwarsaw.coach_erevu.model.Question; -import com.ryanwarsaw.coach_erevu.model.Week; +import com.ryanwarsaw.coach_erevu.model.Topic; public class QuizActivity extends AppCompatActivity implements View.OnClickListener { - private Week week; + private Topic topic; private Question question; private AnswerAdapter answerAdapter; private int currentIndex = 0; + private Preferences preferences; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_quiz); - final String payload = getIntent().getStringExtra("payload"); - week = new GsonBuilder().create().fromJson(payload, Week.class); + final Gson gson = new GsonBuilder().create(); + topic = gson.fromJson(getIntent().getStringExtra("topic"), Topic.class); + preferences = gson.fromJson(getIntent().getStringExtra("preferences"), Preferences.class); - populateQuestion(currentIndex); + inflateQuestion(currentIndex); } - private void populateQuestion(int index) { - question = week.getQuestions().get(index); + private void inflateQuestion(int index) { + question = topic.getQuestions().get(index); currentIndex = index; // Update the header text with current question index. final TextView headerText = findViewById(R.id.header_text); - headerText.setText(week.getTitle() + " : " + getResources().getString(R.string.question) + " (" + - (currentIndex + 1) + " " + getResources().getString(R.string.of) + " " + week.getQuestions().size() + ")"); + headerText.setText(getString(R.string.question_header, topic.getTitle(), + currentIndex + 1, topic.getQuestions().size())); // Update the question text with the current question. final TextView questionText = findViewById(R.id.question_text); @@ -91,9 +96,9 @@ private void populateQuestion(int index) { public void advanceToNextQuestion() { // Populate the next question if we have remaining questions, otherwise finish activity. - if (currentIndex + 1 < week.getQuestions().size()) { + if (currentIndex + 1 < topic.getQuestions().size()) { // We have not completed the quiz yet, so let's move onto the next question. - populateQuestion(++currentIndex); + inflateQuestion(++currentIndex); } else { // Build the dialog to inform the user they've finished the quiz, and present it to them. AlertDialog alertDialog = new AlertDialog.Builder(this).create(); @@ -129,6 +134,7 @@ public void onClick(View v) { Bundle args = new Bundle(); args.putString("correct_answer", question.getAnswers().get(question.getCorrectAnswerIndex() - 1)); args.putString("answer_explanation", question.getAnswerExplanation()); + args.putString("preferences", new GsonBuilder().create().toJson(preferences)); fragment.setArguments(args); fragment.show(getFragmentManager(), "wrong_answer_dialog"); } @@ -147,8 +153,10 @@ public void onClick(View v) { // Close the keyboard if it's still open and accessible to the user. InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - inputManager.hideSoftInputFromWindow((getCurrentFocus() == null) ? null - : getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); + if (inputManager != null) { + inputManager.hideSoftInputFromWindow((getCurrentFocus() == null) ? null + : getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); + } // Advance to the next question programmatically, and update the view. advanceToNextQuestion(); diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/TopicActivity.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/TopicActivity.java new file mode 100644 index 0000000..8186cf0 --- /dev/null +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/TopicActivity.java @@ -0,0 +1,34 @@ +package com.ryanwarsaw.coach_erevu.activity; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.widget.ListView; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.ryanwarsaw.coach_erevu.R; +import com.ryanwarsaw.coach_erevu.adapter.TopicAdapter; +import com.ryanwarsaw.coach_erevu.model.Category; +import com.ryanwarsaw.coach_erevu.model.Preferences; + +public class TopicActivity extends AppCompatActivity { + + private Category category; + private Preferences preferences; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_topic); + + final Gson gson = new GsonBuilder().create(); + final Intent intent = getIntent(); + + category = gson.fromJson(intent.getStringExtra("category"), Category.class); + preferences = gson.fromJson(intent.getStringExtra("preferences"), Preferences.class); + + ((ListView) findViewById(R.id.topic_list_options)) + .setAdapter(new TopicAdapter(this, category, preferences)); + } +} diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/VideoActivity.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/VideoActivity.java index 0dfe6c9..cbfbb45 100644 --- a/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/VideoActivity.java +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/activity/VideoActivity.java @@ -5,6 +5,7 @@ import android.os.Environment; import android.support.v7.app.AppCompatActivity; import android.view.View; + import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player.DefaultEventListener; @@ -20,19 +21,26 @@ import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.FileDataSource; import com.google.android.exoplayer2.upstream.FileDataSource.FileDataSourceException; +import com.google.gson.GsonBuilder; import com.ryanwarsaw.coach_erevu.MainActivity; import com.ryanwarsaw.coach_erevu.R; +import com.ryanwarsaw.coach_erevu.model.Preferences; + import java.io.File; public class VideoActivity extends AppCompatActivity { private SimpleExoPlayer exoPlayer; + private Preferences preferences; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_video); + preferences = new GsonBuilder().create() + .fromJson(getIntent().getStringExtra("preferences"), Preferences.class); + exoPlayer = ExoPlayerFactory.newSimpleInstance(this, new DefaultTrackSelector()); PlayerView playerView = findViewById(R.id.video_player); diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/AnswerAdapter.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/AnswerAdapter.java index 5e5cbaa..f791bde 100644 --- a/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/AnswerAdapter.java +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/AnswerAdapter.java @@ -8,6 +8,7 @@ import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.Button; + import com.ryanwarsaw.coach_erevu.R; import com.ryanwarsaw.coach_erevu.activity.QuizActivity; import com.ryanwarsaw.coach_erevu.model.Question; @@ -23,13 +24,16 @@ public AnswerAdapter(@NonNull Context context, Question question) { this.question = question; } + @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { View answerOption = convertView != null ? convertView : LayoutInflater.from(context).inflate(R.layout.menu_item, parent, false); final Button button = answerOption.findViewById(R.id.menu_button); + button.setText(question.getAnswers().get(position)); button.setOnClickListener((QuizActivity) context); + return answerOption; } } diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/CategoryAdapter.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/CategoryAdapter.java new file mode 100644 index 0000000..bf85659 --- /dev/null +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/CategoryAdapter.java @@ -0,0 +1,70 @@ +package com.ryanwarsaw.coach_erevu.adapter; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.LayerDrawable; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.Button; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.ryanwarsaw.coach_erevu.MainActivity; +import com.ryanwarsaw.coach_erevu.R; +import com.ryanwarsaw.coach_erevu.activity.TopicActivity; +import com.ryanwarsaw.coach_erevu.model.Category; +import com.ryanwarsaw.coach_erevu.model.Curriculum; + +public class CategoryAdapter extends ArrayAdapter { + + private Context context; + private Curriculum curriculum; + + public CategoryAdapter(@NonNull Context context, Curriculum curriculum) { + super(context, R.layout.menu_item, curriculum.getCategories()); + this.context = context; + this.curriculum = curriculum; + } + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + View menuItem = convertView != null ? + convertView : LayoutInflater.from(context).inflate(R.layout.menu_item, parent, false); + final Button button = menuItem.findViewById(R.id.menu_button); + final Category category = curriculum.getCategories().get(position); + + button.setText(category.getTitle()); + + // Dynamically change the button background color based on the content file, without changing + // the rest of the drawable element's background(s), or other instances of the drawable. + ((GradientDrawable) ((LayerDrawable) button.getBackground().mutate()) + .findDrawableByLayerId(R.id.button_background)) + .setColor(Color.parseColor(category.getColor())); + + // Build the intent to launch the topic selector when the user clicks on the button. + button.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + final Button button = view.findViewById(R.id.menu_button); + final Category category = curriculum.findCategoryByTitle((String) button.getText()); + final Intent intent = new Intent(context, TopicActivity.class); + final Gson gson = new GsonBuilder().create(); + + MainActivity.getLoggingHandler().write(CategoryAdapter.this.getClass() + .getSimpleName(), "CATEGORY_SELECTED", category.getTitle()); + intent.putExtra("category", gson.toJson(category)); + intent.putExtra("preferences", gson.toJson(curriculum.getPreferences())); + + context.startActivity(intent); + } + }); + + return menuItem; + } +} diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/MenuAdapter.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/MenuAdapter.java deleted file mode 100644 index 6a9ffa9..0000000 --- a/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/MenuAdapter.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.ryanwarsaw.coach_erevu.adapter; - -import android.content.Context; -import android.content.Intent; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.Button; -import com.google.gson.GsonBuilder; -import com.ryanwarsaw.coach_erevu.MainActivity; -import com.ryanwarsaw.coach_erevu.R; -import com.ryanwarsaw.coach_erevu.activity.ActionActivity; -import com.ryanwarsaw.coach_erevu.model.Curriculum; -import com.ryanwarsaw.coach_erevu.model.Week; - -public class MenuAdapter extends ArrayAdapter { - - private Context context; - private Curriculum curriculum; - - public MenuAdapter(@NonNull Context context, Curriculum curriculum) { - super(context, R.layout.menu_item, curriculum.getWeeks()); - this.context = context; - this.curriculum = curriculum; - } - - @Override - public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { - View menuItem = convertView != null ? - convertView : LayoutInflater.from(context).inflate(R.layout.menu_item, parent, false); - final Button button = menuItem.findViewById(R.id.menu_button); - button.setText(curriculum.getWeeks().get(position).getTitle()); - button.setOnClickListener(new View.OnClickListener() { - public void onClick(View view) { - final Button button = view.findViewById(R.id.menu_button); - final Week week = curriculum.findWeekByTitle((String) button.getText()); - - MainActivity.getLoggingHandler().write(MenuAdapter.this.getClass().getSimpleName(), "MENU_SELECTED", week.getTitle()); - - final Intent intent = new Intent(context, ActionActivity.class); - intent.putExtra("payload", new GsonBuilder().create().toJson(week)); - context.startActivity(intent); - } - }); - return menuItem; - } -} diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/TopicAdapter.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/TopicAdapter.java new file mode 100644 index 0000000..3c37969 --- /dev/null +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/adapter/TopicAdapter.java @@ -0,0 +1,72 @@ +package com.ryanwarsaw.coach_erevu.adapter; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.LayerDrawable; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.Button; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.ryanwarsaw.coach_erevu.MainActivity; +import com.ryanwarsaw.coach_erevu.R; +import com.ryanwarsaw.coach_erevu.activity.ActionActivity; +import com.ryanwarsaw.coach_erevu.model.Category; +import com.ryanwarsaw.coach_erevu.model.Preferences; +import com.ryanwarsaw.coach_erevu.model.Topic; + +public class TopicAdapter extends ArrayAdapter { + + private Context context; + private Category category; + private Preferences preferences; + + public TopicAdapter(@NonNull Context context, Category category, Preferences preferences) { + super(context, R.layout.menu_item, category.getTopics()); + this.context = context; + this.category = category; + this.preferences = preferences; + } + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + View menuItem = convertView != null ? + convertView : LayoutInflater.from(context).inflate(R.layout.menu_item, parent, false); + final Button button = menuItem.findViewById(R.id.menu_button); + final Topic topic = category.getTopics().get(position); + + button.setText(topic.getTitle()); + + // Dynamically change the button background color based on the content file, without changing + // the rest of the drawable element's background(s), or other instances of the drawable. + ((GradientDrawable) ((LayerDrawable) button.getBackground().mutate()) + .findDrawableByLayerId(R.id.button_background)) + .setColor(Color.parseColor(topic.getColor())); + + button.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + final Button button = view.findViewById(R.id.menu_button); + final Topic topic = category.findTopicByTitle((String) button.getText()); + final Intent intent = new Intent(context, ActionActivity.class); + final Gson gson = new GsonBuilder().create(); + + MainActivity.getLoggingHandler().write(TopicAdapter.this.getClass() + .getSimpleName(), "TOPIC_SELECTED", topic.getTitle()); + intent.putExtra("topic", gson.toJson(topic)); + intent.putExtra("preferences", gson.toJson(preferences)); + + context.startActivity(intent); + } + }); + + return menuItem; + } +} diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/fragment/WrongAnswerFragment.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/fragment/WrongAnswerFragment.java index 92c479d..692c9ea 100644 --- a/app/src/main/java/com/ryanwarsaw/coach_erevu/fragment/WrongAnswerFragment.java +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/fragment/WrongAnswerFragment.java @@ -4,21 +4,31 @@ import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.DialogFragment; -import android.content.Context; +import android.app.Presentation; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; +import android.graphics.Color; import android.os.Bundle; import android.view.View; import android.widget.ListView; + +import com.google.gson.GsonBuilder; import com.ryanwarsaw.coach_erevu.R; import com.ryanwarsaw.coach_erevu.activity.QuizActivity; +import com.ryanwarsaw.coach_erevu.model.Preferences; public class WrongAnswerFragment extends DialogFragment { + private Preferences preferences; + @Override public Dialog onCreateDialog(Bundle savedInstanceState) { super.onCreateDialog(savedInstanceState); AlertDialog.Builder builder = new Builder(getActivity()); + + preferences = new GsonBuilder().create().fromJson( + getArguments().getString("preferences"), Preferences.class); + String dialogString = getResources().getString(R.string.wrong_answer_dialog) + " \"" + getArguments().getString("correct_answer") + ".\""; @@ -48,6 +58,7 @@ public void onCancel(DialogInterface dialog) { @Override public void onStart() { super.onStart(); - ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getResources().getColor(R.color.buttonDark)); + ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_POSITIVE) + .setTextColor(Color.parseColor(preferences.getWrongAnswerButtonColor())); } } diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/logging/LoggingHandler.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/logging/LoggingHandler.java index 6a531d1..8fa7310 100644 --- a/app/src/main/java/com/ryanwarsaw/coach_erevu/logging/LoggingHandler.java +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/logging/LoggingHandler.java @@ -2,6 +2,7 @@ import android.os.Environment; import android.text.TextUtils; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -11,15 +12,14 @@ public class LoggingHandler { - private File externalFile; private PrintWriter printWriter; private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd 'at' HH:mm:ss z"); public LoggingHandler(String fileName) { try { - this.externalFile = new File(Environment.getExternalStoragePublicDirectory( - Environment.DIRECTORY_DOWNLOADS), fileName); - this.externalFile.createNewFile(); + File externalFile = new File(Environment.getExternalStoragePublicDirectory( + Environment.DIRECTORY_DOWNLOADS), fileName); + externalFile.createNewFile(); this.printWriter = new PrintWriter(new FileOutputStream(externalFile, true), false); } catch (IOException e) { e.printStackTrace(); diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Category.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Category.java new file mode 100644 index 0000000..93f6253 --- /dev/null +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Category.java @@ -0,0 +1,32 @@ +package com.ryanwarsaw.coach_erevu.model; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.ToString; + +@ToString +@Getter(AccessLevel.PUBLIC) +public class Category { + + @SerializedName("title") + private String title; + + @SerializedName("color") + private String color; + + @SerializedName("topics") + private List topics; + + public Topic findTopicByTitle(String title) { + for (Topic topic : getTopics()) { + if (topic.getTitle().equalsIgnoreCase(title)) { + return topic; + } + } + return null; + } +} diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Curriculum.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Curriculum.java index 909725b..658179a 100644 --- a/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Curriculum.java +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Curriculum.java @@ -1,7 +1,9 @@ package com.ryanwarsaw.coach_erevu.model; import com.google.gson.annotations.SerializedName; + import java.util.List; + import lombok.AccessLevel; import lombok.Getter; import lombok.ToString; @@ -11,14 +13,19 @@ public class Curriculum { @SerializedName("version") - public int version; + private int version; + + @SerializedName("preferences") + private Preferences preferences; - @SerializedName("weeks") - public List weeks; + @SerializedName("categories") + private List categories; - public Week findWeekByTitle(String title) { - for (Week week : weeks) { - if (week.title == title) return week; + public Category findCategoryByTitle(String title) { + for (Category category : getCategories()) { + if (category.getTitle().equalsIgnoreCase(title)) { + return category; + } } return null; } diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Preferences.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Preferences.java new file mode 100644 index 0000000..b25ba43 --- /dev/null +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Preferences.java @@ -0,0 +1,21 @@ +package com.ryanwarsaw.coach_erevu.model; + +import com.google.gson.annotations.SerializedName; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.ToString; + +@ToString +@Getter(AccessLevel.PUBLIC) +public class Preferences { + + @SerializedName("quiz-button-color") + private String quizButtonColor; + + @SerializedName("video-button-color") + private String videoButtonColor; + + @SerializedName("wrong-answer-button-color") + private String wrongAnswerButtonColor; +} diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Question.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Question.java index 663711b..c190072 100644 --- a/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Question.java +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Question.java @@ -1,7 +1,9 @@ package com.ryanwarsaw.coach_erevu.model; import com.google.gson.annotations.SerializedName; + import java.util.List; + import lombok.AccessLevel; import lombok.Getter; import lombok.ToString; @@ -11,17 +13,17 @@ public class Question { @SerializedName("question") - public String question; + private String question; @SerializedName("answer-type") - public String answerType; + private String answerType; @SerializedName("answers") - public List answers; + private List answers; @SerializedName("correct-answer") - public int correctAnswerIndex; + private int correctAnswerIndex; @SerializedName("answer-explanation") - public String answerExplanation; + private String answerExplanation; } diff --git a/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Week.java b/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Topic.java similarity index 65% rename from app/src/main/java/com/ryanwarsaw/coach_erevu/model/Week.java rename to app/src/main/java/com/ryanwarsaw/coach_erevu/model/Topic.java index 6841ed3..784f004 100644 --- a/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Week.java +++ b/app/src/main/java/com/ryanwarsaw/coach_erevu/model/Topic.java @@ -1,27 +1,29 @@ package com.ryanwarsaw.coach_erevu.model; import com.google.gson.annotations.SerializedName; + import java.util.List; + import lombok.AccessLevel; import lombok.Getter; import lombok.ToString; @ToString @Getter(AccessLevel.PUBLIC) -public class Week { +public class Topic { @SerializedName("id") - public int id; + private int id; @SerializedName("title") - public String title; + private String title; - @SerializedName("topic") - public String topic; + @SerializedName("color") + private String color; @SerializedName("video") - public String videoName; + private String videoName; @SerializedName("questions") - public List questions; + private List questions; } diff --git a/app/src/main/res/drawable/button_dark.xml b/app/src/main/res/drawable/button.xml similarity index 76% rename from app/src/main/res/drawable/button_dark.xml rename to app/src/main/res/drawable/button.xml index fa25f4d..ead822a 100644 --- a/app/src/main/res/drawable/button_dark.xml +++ b/app/src/main/res/drawable/button.xml @@ -1,11 +1,11 @@ - + - + - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_action.xml b/app/src/main/res/layout/activity_action.xml index b5720a6..7277489 100644 --- a/app/src/main/res/layout/activity_action.xml +++ b/app/src/main/res/layout/activity_action.xml @@ -9,7 +9,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/menu_item.xml b/app/src/main/res/layout/menu_item.xml index c478661..a35e929 100644 --- a/app/src/main/res/layout/menu_item.xml +++ b/app/src/main/res/layout/menu_item.xml @@ -6,5 +6,5 @@ android:layout_height="wrap_content" android:padding="25dp" android:textSize="25sp" - android:background="@drawable/button_light" + android:background="@drawable/button" style="?android:attr/borderlessButtonStyle"/> \ No newline at end of file diff --git a/app/src/main/res/raw/content.json b/app/src/main/res/raw/content.json index b998ac7..1bb6915 100644 --- a/app/src/main/res/raw/content.json +++ b/app/src/main/res/raw/content.json @@ -1,374 +1,102 @@ { "version": 1, - "weeks": [ + "preferences": { + "quiz-button-color": "#59A4CB", + "video-button-color": "#5ACBF0", + "wrong-answer-button-color": "#59A4CB" + }, + "categories": [ { - "id": "0", - "title": "Intangamarara", - "topic": "Akabazo ka SEL ni iki", - "video": "intro.mp4", - "questions": [ - { - "question": "Ni ikihe ciyumviro rusangi cawe kijanye n’ugukunda iyi reresi?", - "answer-type": "multiple-choice", - "answers": [ - "Nayikunze kandi yari ngirakamaro cane", - "Ndi ntaho mpagaze kandi niyumvira ko itari ngirakamaro canke ataco imaze", - "Sinanezerejwe n’iyi reresi kandi niyumviriye ko itari ngirakamaro" + "title": "January", + "color": "#FF6347", + "topics": [ + { + "id": 0, + "title": "Introduction", + "color": "#333333", + "video": "week1.mp4", + "questions": [ + { + "question": "What was your overall impression of this video?", + "answer-type": "multiple-choice", + "answers": [ + "I loved it and it was very useful.", + "I am neutral and I think it was neither useful nor useless.", + "I did not enjoy the video and I thought it was not useful." + ] + } ] - }, - { - "question": "Ni nde yariko avugana nawe muri iyi reresi?", - "answer-type": "free-text" - }, - { - "question": "Ni ikihe ciyumviro rusangi cawe kijanye n’ugukunda uwo muntu?", - "answer-type": "multiple-choice", - "answers": [ - "Uyu muntu araciye ubwenge cane kandi yatumye ndabikunda", - "Sindabizi neza", - "Uyu muntu ntabushobozi afise bw’ukugira ico anyigishije" - ] - }, - { - "question": "Ni uwuhe murwi muri iyi mirwi werekanywe muri iyi reresi?", - "answer-type": "multiple-choice", - "answers": [ - "Ukutigera udohoka namba", - "Ama udohoka", - "Ugutunganya umwanya wawe" - ], - "correct-answer": 1 - }, - { - "question": "Ni uwuhe murwi muri iyi mirwi werekanywe muri iyi reresi?", - "answer-type": "multiple-choice", - "answers": [ - "Ugutunganya ubushakashatsi bwawe", - "Ugutunganya intego yawe", - "Ukugenzura inyiyumvo zawe" - ], - "correct-answer": 3 - }, - { - "question": "Ni uwuhe murwi muri iyi mirwi werekanywe muri iyi reresi?", - "answer-type": "multiple-choice", - "answers": [ - "Ukwubaka inzu yawe", - "Ukwubaka ubwonko bwawe", - "Ukwubaka ibishobisho vyawe" - ], - "correct-answer": 2 - }, - { - "question": "Ni uwuhe murwi muri iyi mirwi werekanywe muri iyi reresi?", - "answer-type": "multiple-choice", - "answers": [ - "Ukwongereza ubumenyi bw’ugusoma", - "Ugutahura ivyisungwa", - "Ugutatura impari hamwe n’indwano" - ], - "correct-answer": 3 - }, - { - "question": "Ni uwuhe murwi muri iyi mirwi werekanywe muri iyi reresi?", - "answer-type": "multiple-choice", - "answers": [ - "Ugukorera mu runani rwiza", - "Ukwongereza ubumenyi mu biharuro", - "Ugushika kw’ishure ku gihe" - ], - "correct-answer": 1 - }, - { - "question": "Mwakoze gukorera hamwe aka kabazo nk’umurwi. Hoba hari ikindi kintu mwipfuza kwongerako nk’ukugira ico mubivuzeko?", - "answer-type": "free-text" } ] }, { - "id": "1", - "title": "Igikorwa ca 1", - "topic": "Samuel Avuze", - "video": "samuelavuze.mp4", - "questions": [ - { - "question": "Ni ikihe ciyumviro rusangi cawe kijanye n’ugukunda iyi reresi?", - "answer-type": "multiple-choice", - "answers": [ - "Nayikunze kandi yari ngirakamaro cane", - "Ndi ntaho mpagaze kandi niyumvira ko itari ngirakamaro canke ataco imaze", - "Sinanezerejwe n’iyi reresi kandi niyumviriye ko itari ngirakamaro" + "title": "February", + "color": "#FFD700", + "topics": [ + { + "id": 0, + "title": "Introduction", + "color": "#333333", + "video": "week1.mp4", + "questions": [ + { + "question": "What was your overall impression of this video?", + "answer-type": "multiple-choice", + "answers": [ + "I loved it and it was very useful.", + "I am neutral and I think it was neither useful nor useless.", + "I did not enjoy the video and I thought it was not useful." + ] + } ] - }, - { - "question": "Ni ikihe gice c’ireresi cabaye ngirakamaro cane?", - "answer-type": "free-text" - }, - { - "question": "Ni ubuhe bushobozi buri muri iyi reresi?", - "answer-type": "multiple-choice", - "answers": [ - "Ukugenzura inyiyumvo zawe", - "Ukwubaka ubwonko bwawe", - "Ugutatura impari hamwe n’amatati" - ], - "correct-answer": 2 - }, - { - "question": "Ni iyihe ntumbero y’aka gakino?", - "answer-type": "multiple-choice", - "answers": [ - "Gufasha abana kwumviriza hamwe n’ukugenzura ibikorwa vyabo", - "Gufasha abana kwiga ibintu bishasha", - "Gufasha abana gukorera mu runani" - ], - "correct-answer": 1 - }, - { - "question": "Ni ryari abana bategerezwa kwigana ibikorwa bikorwa n’umwigisha?", - "answer-type": "multiple-choice", - "answers": [ - "Mu gihe umwigisha avuze ngo \"nyiganga\"", - "Mu gihe umwigisha avuze ngo \"Samuel Avuze\"", - "Mu gihe umwigisha anumye" - ], - "correct-answer": 2 - }, - { - "question": "Ni ibihe bintu utegerezwa kuba uriko urakora?", - "answer-type": "multiple-choice", - "answers": [ - "Ntegerezwa kubwira abanyeshure kwicara iyo bakoze ico mvuze ntatanguje \"Samuel Avuze\"", - "Ntegerezwa guhana abanyeshure bakora ukutariko", - "Ntegerezwa kunyarutsa cane umwanya wose" - ], - "correct-answer": 1 - }, - { - "question": "Ni ibihe bindi bintu udategerezwa kuba uriko urakora?", - "answer-type": "multiple-choice", - "answers": [ - "Sintegerezwa kuvuga ngo \"Samuel Avuze\"", - "Sintegerezwa gutuma abana bimuka bava mu kibanza cabo", - "Sintegerezwa kuvuga ibijanye n’ivyo turiko turiga" - ], - "correct-answer": 2 - }, - { - "question": "Ni ikihe kintu udategerezwa kuba uriko urakora?", - "answer-type": "multiple-choice", - "answers": [ - "Sintegerezwa gutwenga", - "Sintegerezwa kuba mwiza", - "Sintegerezwa guhana abanyeshure bakoze amakosha" - ], - "correct-answer": 3 - }, - { - "question": "Ni ikihe kintu udategerezwa kuba uriko urakora?", - "answer-type": "multiple-choice", - "answers": [ - "Sintegerezwa kwambara ishati isa n’ubururu", - "Sintegerezwa kuvuga ngo \"Samuel Avuze\" incuro nyinshi cane nikurikiranya", - "Sintegerezwa gusimba" - ], - "correct-answer": 2 - }, - { - "question": "Fata umwanya mutoyi muganire n’abagenzi banyu hanyuma mushireho ihangiro ryo mu ndwi iza. Ni gute mushaka kwimenyereza SEL mu ndwi iza? Fata urupapuro rwawe wuzuze aho hagaragara.", - "answer-type": "free-text" } ] }, { - "id": "2", - "title": "Igikorwa ca 2", - "topic": "Nyigana", - "video": "nyigana.mp4", - "questions": [ - { - "question": "Ni ikihe ciyumviro rusangi cawe kijanye n’ugukunda iyi reresi?", - "answer-type": "multiple-choice", - "answers": [ - "Nayikunze kandi yari ngirakamaro cane", - "Ndi ntaho mpagaze kandi niyumvira ko itari ngirakamaro canke ataco imaze", - "Sinanezerejwe n’iyi reresi kandi niyumviriye ko itari ngirakamaro" + "title": "March", + "color": "#6495ED", + "topics": [ + { + "id": 0, + "title": "Introduction", + "color": "#333333", + "video": "week1.mp4", + "questions": [ + { + "question": "What was your overall impression of this video?", + "answer-type": "multiple-choice", + "answers": [ + "I loved it and it was very useful.", + "I am neutral and I think it was neither useful nor useless.", + "I did not enjoy the video and I thought it was not useful." + ] + } ] - }, - { - "question": "Ni ikihe gice c’ireresi cabaye ngirakamaro cane?", - "answer-type": "free-text" - }, - { - "question": "Ni ubuhe bushobozi buri muri iyi reresi?", - "answer-type": "multiple-choice", - "answers": [ - "Ukugenzura ibishobisho vyawe", - "Ukwubaka ubwonko bwawe", - "Ugutatura impari hamwe n’amatati" - ], - "correct-answer": 1 - }, - { - "question": "Abana bazokwiga iki mu gukora iki gikorwa? ", - "answer-type": "multiple-choice", - "answers": [ - "Abana bazokwiga ibintu bishasha", - "Bazokwiga ukuntu ibishobisho bimeze kandi bavyiyumvemwo ubwabo hamwe n’abandi", - "Bazokwiga ukuntu bakorera mu runani" - ], - "correct-answer": 2 - }, - { - "question": "Ni ibiki umurongozi ategerezwa kwerekana?", - "answer-type": "multiple-choice", - "answers": [ - "Ikintu coroshe gusubiramwo, nk’intambo", - "Ikintu kigoye gusubiramwo, nk’ururirimbo", - "Ibishobisho" - ], - "correct-answer": 3 - }, - { - "question": "Ni ikintu ikihe utegerezwa kuba uriko urakora?", - "answer-type": "multiple-choice", - "answers": [ - "Ntegerezwa gutanga uburorero bw’ibishobisho nyezina", - "Ntegerezwa guhana abanyeshure bakora ukutariko", - "Ntegerezwa kubwira abanyeshure kunyarutsa" - ], - "correct-answer": 1 - }, - { - "question": "Ni ikintu ikihe utegerezwa kuba uriko urakora?", - "answer-type": "multiple-choice", - "answers": [ - "Ntegerezwa kwirukanga mw’isomero", - "Ntegerezwa kwerekana ibishobisho kandi nkakosora abanyeshure mu bwitonzi", - "Ntegerezwa gusaba buri wese kwigirisha nk’uwushavuye" - ], - "correct-answer": 2 - }, - { - "question": "Ni ikintu ikihe udategerezwa kuba uriko urakora?", - "answer-type": "multiple-choice", - "answers": [ - "Sintegerezwa gutwenga", - "Sintegerezwa kwerekana ibikorwa atari ibishobisho", - "Sintegerezwa kuba mwiza" - ], - "correct-answer": 2 - }, - { - "question": "Ni ikintu ikihe udategerezwa kuba uriko urakora?", - "answer-type": "multiple-choice", - "answers": [ - "Sintegerezwa gusimba", - "Sintegerezwa kureka abanyeshure ngo bavuge ibishobisho vyabo, bategerezwa kuba bariko baravyerekana gusa", - "Sintegerezwa gutera intege abana" - ], - "correct-answer": 2 - }, - { - "question": "Fata umwanya mutoyi muganire na bagenzi banyu hanyuma mutunganye ihangiro ryo mu ndwi iza. Ni gute ushaka kuzogerageza SEL mu ndwi iza? Fata urupapuro rwawe, hanyuma wuzuze aho hagaragara.", - "answer-type": "free-text" } ] }, { - "id": "3", - "title": "Igikorwa ca 3", - "topic": "Guma kw’ihangiro", - "video": "gumakwihangiro.mp4", - "questions": [ - { - "question": "Ni ikihe ciyumviro rusangi cawe kijanye n’ugukunda iyi reresi?", - "answer-type": "multiple-choice", - "answers": [ - "Nayikunze kandi yari ngirakamaro cane", - "Ndi ntaho mpagaze kandi niyumvira ko itari ngirakamaro canke ataco imaze", - "Sinanezerejwe n’iyi reresi kandi niyumviriye ko itari ngirakamaro" + "title": "April", + "color": "#9370DB", + "topics": [ + { + "id": 0, + "title": "Introduction", + "color": "#333333", + "video": "week1.mp4", + "questions": [ + { + "question": "What was your overall impression of this video?", + "answer-type": "multiple-choice", + "answers": [ + "I loved it and it was very useful.", + "I am neutral and I think it was neither useful nor useless.", + "I did not enjoy the video and I thought it was not useful." + ] + } ] - }, - { - "question": "Ni ikihe gice c’ireresi cabaye ngirakamaro cane?", - "answer-type": "free-text" - }, - { - "question": "Ni ubuhe bushobozi buri muri iyi reresi?", - "answer-type": "multiple-choice", - "answers": [ - "Ugukorera mu runani rwiza", - "Ukutigera udohoka namba", - "Ukwubaka ubwonko bwawe" - ], - "correct-answer": 2 - }, - { - "question": "Abana bazokwiga iki mu gukora iki gikorwa?", - "answer-type": "multiple-choice", - "answers": [ - "Bazokwiga gukorera mu runani rwiza", - "Bazokwiga gutunganya amahangiro ashoboka kandi batunganye integuro", - "Bazokwiga ukuntu bakurikirana" - ], - "correct-answer": 2 - }, - { - "question": "Mu gihe abanyeshure badashoboye gutanga ihangiro ni gute ushobora kubafasha?", - "answer-type": "multiple-choice", - "answers": [ - "Kubabwira mu gishingo cavyo bashushanye ishusho y’umuryango wabo", - "Gusabikanya uburorero bw’amahangiro yawe bwite mu kubikundisha abanyeshure", - "Kubwira abanyeshure ngo ntihagire ico baterera" - ], - "correct-answer": 2 - }, - { - "question": "Ni ikintu ikihe utegerezwa kuba uriko urakora?", - "answer-type": "multiple-choice", - "answers": [ - "Ntegerezwa gufasha abanyeshure kugira intambwe nyezina, zigezweko kandi zikorwa", - "Ntegerezwa kuvuga gusa ivyerekeye amahangiro yanje", - "Ntegerezwa kubwira abanyeshure ko amahangiro yabo atari yo." - ], - "correct-answer": 1 - }, - { - "question": "Ni ikintu ikihe udategerezwa kuba uriko urakora?", - "answer-type": "multiple-choice", - "answers": [ - "Ntegerezwa gusaba abanyeshure kwerekana amahangiro yabo", - "Ntegerezwa gutanga uburorero bw’ibishobisho", - "Ntegerezwa kwumviriza neza abanyeshure hamwe n’ukubaha ivyiyumviro" - ], - "correct-answer": 3 - }, - { - "question": "Ni ikintu ikihe udategerezwa kuba uriko urakora?", - "answer-type": "multiple-choice", - "answers": [ - "Sintegerezwa gutera intege abanyeshure", - "Sintegerezwa kubwira abana igitegerezwa kuba amahangiro yabo", - "Sintegerezwa kuba mwiza" - ], - "correct-answer": 2 - }, - { - "question": "Ni ikintu ikihe udategerezwa kuba uriko urakora?", - "answer-type": "multiple-choice", - "answers": [ - "Sintegerezwa kwitwararika mu mwanya w’igikorwa", - "Sintegerezawa guhitamwo abana barenga 2 ngo basabikanye amahangiro hamwe n’intambwe vyabo", - "Sintegerezwa gutera intege abana" - ], - "correct-answer": 2 - }, - { - "question": "Fata umwanya mutoyi muganire na bagenzi banyu hanyuma mutunganye ihangiro ryo mu ndwi iza. Ni gute mushaka kwimenyereza SEL mu ndwi iza? Fata urupapuro rwawe, hanyuma wuzuze aho hagaragara.", - "answer-type": "free-text" } ] } ] -} +} \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 016ab3e..939367d 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,8 +3,7 @@ #000 #000 #FF4081 - #5ACBF0 - #59A4CB + #5ACBF0 #000 #000 #000 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b00d62b..9a2c695 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,9 +6,10 @@ Ni vyiza Ikibazo ca muri - Injiza inyishu yawe ngaha... + Injiza inyishu yawe ngaha… Ivyo si vyo. Inyishu nziza ni: Impera y\'akabazo! Ndagushimiye kubw\'ukwiga ibijanye na ibishobisho hamwe no kubw\'ukwishura ibi bibazo vyose. Uri imboneza y\'abanyeshure. Uguherahezwa kw\'akabazo Hitamwo kimwe: - + %1$s : Ikibazo ca (%2$d muri %3$d) + \ No newline at end of file diff --git a/build.gradle b/build.gradle index eccff49..43c0708 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.1' + classpath 'com.android.tools.build:gradle:3.1.3' // NOTE: Do not place your application dependencies here; they belong