Wednesday, March 25, 2015

MyNotes: Cutting it Close

If any of you notice the commit dates in my repository, you will notice that the commits pre-date the blog entries.  I also try to publish one blog entry per week.  This gives me a nice buffer for the times that life just gets in the way.

My day job has been incredibly busy the last few weeks and I haven't had much time to work on this project in the evenings so that is why there is a big gap.  I was also laying the groundwork for a lot of UI work and that takes some time that I just haven't had lately. 

This last weekend I decided to make a big push to get the changes ready before my buffer entries ran out.  I made late on Sunday.  WooHoo!!

That being said I pushed several major changes today that we will take one step at a time over the next few entries.  

The good news is that I finally have the UI and data scaffolding in place.  Yea!

Wednesday, March 18, 2015

MyNotes: Code Style

Before I get deep into coding I want to take a minute to talk about my code style guidelines.  I have guidelines for the code, XML layouts and XML resource values.

Code Style

I basically follow the Android Contributors Guidelines.  This is includes a very simplified Hungarian notation that prefixes an "m" to all class attributes.  I go a step further and prefix an "s" to all non-final static objects.  I also use all caps with underscores for static final variables.  It ends up looking like this:

class MyClass {
      private static final Object THIS_IS_FINAL_AND_STATIC = new Object();
     
      private static Object sThisIsNotFinal = new Object();
     
      private int mObjectAttribute = new Object();
}

XML Layouts

Firstly, I try to name the files to signify what is inside.  I start the file name with what the layout is for:
  • Activity layouts:
    • activity_main.xml
    • activity_note_edit.xml
  • Fragment layouts:
    • fragment_main_toolbar.xml
    • fragment_note_filter.xml
  • Custom Components:
    • component_note.xml
    • component_grid,xml
  • Include Layouts:
    • include_activity_main_content.xml
    • include_subtoolbar.xml
  • Item to use in RecyclerViews:
    • recycler_item_note.xml
    • recycler_item_name.xml
My only other guideline is to be specific and verbose when naming ids. I have problems in the past where really simple id names caused a conflict at runtime. Those are unpleasant bugs to figure out and eliminate.  Since then I nip the problem in the bud by being specific on the names.  So if I have a TextView that will contains a label in an activity layout instead of :
<TextView android:id="@+id/name" />
I will use:
<TextView android:id="@+id/activity_main_first_name_label" />

XML Values

The values files can get out of hand really fast.   To prevent this, I try to only use the default files (strings.xml, colors.xml, etc.) for the global values.  I then group the items based on functionality and put them in their own files.  I always prefix the files with the type of resource it contains (integers, dimen, strings, etc).  It ends up looking like this:

strings.xml
strings_toolbar_strings.xml
strings_help,xml
colors.xml
colors_theme.xml
colors_note.xml



MyNotes: Setting the Mood

One of the first steps of the Material changes is to customize the theme.  For now, I am using the light Material theme as the base theme.  I may add a feature later to let the user switch to a dark theme.

The light themes can be a little hard on the eyes and they are blinding in a dark room, but they are pretty and show the shadows well.

The hard part is that I have to pick my color schemes to use as my application theme.  Google has provide the material color palettes in the design guide.  There also websites that will build your color palette based on a primary color.  The one I used is Material Palette.  Blue happens to be my favorite color, so I used a soft blue-gray as my primary color.  From there it build my palette for me:


To import this into my app requires some XML changes.

Step 1: Value Resource Updates

I like to keep my values resource xml files seperated based on functionality.  I stuck my theme colors in their own xml file named colors_theme.xml with the following content:

<resources>
    <item name="primaryColor" type="color">#607D8B</item>
    <item name="darkPrimaryColor" type="color">#455A64</item>
    <item name="lightPrimaryColor" type="color">#CFD8DC</item>

    <item name="accentColor" type="color">#FF9800</item>
    <item name="accentColorRipple" type="color">#FFE0B2</item>

    <item name="dividerColor" type="color">#b5b6b6</item>
    <item name="secondaryTextColor" type="color">#727272</item>
    <item name="primaryTextColor" type="color">@android:color/black</item>
</resources>

I then created a themes.xml file that contains my app theme style:

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

        <!-- Main theme colors -->
        <item name="colorPrimary">@color/primaryColor</item>
        <item name="colorPrimaryDark">@color/darkPrimaryColor</item>
        <item name="colorAccent">@color/accentColor</item>
        <item name="android:textColorSecondary">@color/secondaryTextColor</item>
        <item name="android:textColorPrimary">@color/primaryTextColor</item>

    </style>
</resources>

Step 2: Manifest Updates

This one is really easy.  I just added an attribute to the application tag to use my app theme:
<application android:name=".MyNotesApplication" android:label="@string/app_name" android:icon="@drawable/my_icon" android:theme="@style/AppTheme">


Commits

That is it. My app now uses my new theme.  Please find the changes at https://github.com/fsk-software/mynotes/commit/7075f9c86d54af9e55015759d04a64169d0cb4c4

Wednesday, March 11, 2015

MyNotes: Injection Framework

The next item on my agenda is to bring in an injection framework.

I am ambivalent towards these frameworks in general.  Using  them has pros and cons.  In the pro column is that it can simplify testing and it definitely cleans up the code.  In the con column is that once you commit to a framework, it is tough to get it back out.  That means that you are bound to features of the framework, so think carefully about it.  
It sounds counter-intuitive, but I generally don't use them for large or complex apps because they cannot be easily removed and the cost to try may be prohibitive.  It also reduces flexibility of moving code to different states of the Fragment and Activity life-cycles.  
I decide to use one in this app because I haven't used one in a real app for quite a while and I want to see if they have improved.  The app is also small enough and simple enough that I can yank the framework out without too much fuss.

If you choose to use a framework, you have a lot of options. My top two candidates are Roboguice and ButterKnife.  
  • Roboguice is a true dependency injection framework and is probably the most common framework to use and support can easily be found in many online forums.  It also has the bonus of working in any class, not just UI classes.  On the downside, is that the injections occur at Runtime, so it can slow down execution and errors aren't caught until Runtime.  It also does not work great in library project due to the resource ids not being unique.  There is a work around, but it kind of sucks.
  • ButterKnife isn't a true dependency injection framework.  It is great at removing all of the boilerplate code from the UI classes, but it only works in the UI objects.  All other classes have to be done the old-fashioned way.  In the plus column, is that the "injections" are down at compile time so the errors are caught there and there isn't a Runtime impact.  It also works in library projects really well.  Plus, I was a big fan of the ActionBarSherlock and ButterKnife was developed by the same person.

Either one should work well within my app,   I hate to admit, but I basically flipped a coin.  It came up heads, so I brought in Roboguice.  I'm still not sold on it and may change my mind later though...

Step 1: Update the MyNotes build.gradle file.

Add a new proguard file for the roboguice to the appropriate area (the file is empty for now):

android { 
    // Library specific proguard files
    ...
    proguardFiles 'proguard-roboguice.pro'
}

Add in the RoboGuice dependencies:
dependencies {
    ....  
    compile 'org.roboguice:roboguice:3.+'
    provided 'org.roboguice:roboblender:3.+'
    ....
}

For the record, I basically just took that right off their webpage.

Step 2: Add the dependency injection to the MainActivity java code.

There isn't much there yet, but it looks like this:

@ContentView(R.layout.main)
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
    }

Commits:

The changes for this entry can be found at https://github.com/fsk-software/mynotes/commit/b41bf9228b7cf9dcf7dc886f501a6804338ddf6d

Wednesday, March 4, 2015

MyNotes: Material Mock

I haven't done any material UI design before so this is my first stab at it.  I am hoping to get the UI to look something like this:

It definitely as a bubblegum vibe to it that I need to get rid of by tweaking colors, but I am happy with the basic concept.

The material design is going to be a learn I go kinda thing, so stay tuned.