Backend Stuff

Josh Miller

This was our third week of production and things got busy. This week, I was in charge of starting backend work for the app, updating the visuals, and implementing some user preference functionality.

The main priority, though, was getting some backend code functional so that the rest of development could continue without more placeholder data. This involved setting up a new data type that can store all the user's information including their goals, body metrics, and workout history, and designing a function that can convert the data into a parse-able file to store in the local app data. The rest of the app can then load the same file, convert it back into useable data types and perform whatever calculations are necessary.
public static CUser LoadUser()
{
SharedPreferences sharedPreferences = ContextRetriever.getContext().getSharedPreferences("shared preferences", Context.MODE_PRIVATE);
Gson gson = new Gson();

String json = sharedPreferences.getString("user", null);
Type type = new TypeToken<CUser>()
{
}.getType();
CUser user = gson.fromJson(json, type);

if (user == null)
{
user = new CUser();
}

return user;
}
The next portion I worked on was converting many of our visuals to more modern material design standards to rely on "Cards" to convey information to the user. I refactored many of our app's layout files, resulting in what in my opinion, is a much cleaner and simpler looking app.
Updated cards for routines

Updated cards for goals

The next feature I worked on implementing was the preferences fragment. Aside from a few preferences, this fragment is now fully functional and the user is able to adjust the various preferences to change aspects of the app to their liking, including metric vs imperial units, the formula used to calculate a one rep max, the default weight increment, and the user's weekly exercise frequency.
Updated settings
App using metric units

I was also able to source a new set of icons to use for our exercise categories, but they were low resolution and the wrong color, so I had some work to do before they could be useable for our app. I first had to split each icon into its own individual file. Next, I performed a color adjustment, removed the background, upscaled each image, and cropped them each to the correct shape and size to use in the app.
Muscle groups

Original source from Simon Chalk
Color corrected and upscaled transparent dark-mode version

After a suggestion from one of our project's producers, I added a search icon in the app's action bar that will allow the user to more easily find an exercise or goal. This involved designing a custom ValueFilter for each adapter for each ListView that needs to be searchable and calling that filter when the user updates the text in the search box.
Below are some snippets of the filtering code designed:
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0)
{
ArrayList<CExerciseGoal> filterList = new ArrayList<CExerciseGoal>();
for (int i = 0; i < mFilterList.size(); i++)
{
if ((mFilterList.get(i).GetTitle().toUpperCase())
.contains(constraint.toString().toUpperCase()))
{
CExerciseGoal goal = mFilterList.get(i);
filterList.add(goal);
}
}
results.count = filterList.size();
results.values = filterList;
} else
{
results.count = mFilterList.size();
results.values = mFilterList;
}
return results;
}
searchView.setOnQueryTextListener(
new SearchView.OnQueryTextListener()
{
@Override
public boolean onQueryTextChange(String newText)
{
goalAdapter.getFilter().filter(newText);
return false;
}
});

Search bar being utilized
I was also able to update the app's splash screen. After testing the app on larger devices, I realized the splash layout was improperly scaling. I resolved this issue by updating the icon used and adding a loading spinner as well.
Updated splash layout
One of the last things I had time to work on this week was an info screen for our app. This provides version information, a way for the user to provide feedback, and a list of everyone involved in the apps production.
Info screen
Finally, I was able to help Austin with retrieving images from our Firebase storage. Together, we were finally able to successfully retrieve images and data from the online database, but we quickly realized there would be an issue with our allotted bandwidth. While each of the images in our app are only around ~100kB, however this will quickly add up, eventually costing us more money than we would like to even display images in the app. After discussing the issue with our producer and mentors, we decided that we could instead move to storing all of the apps necessary assets on the local device.