Writing code at the creation of a fragment

All the examples I’ve seen so far for dealing with programmatically handling things from a view have involved an activity and the layout associated with it. But when I am working with Android Studio, whenever I create a new activity things are a little different and I get two layouts and things are happening in a fragment rather than the first layout. I don’t totally get the whole thing yet, I’m working on wrapping my mind around it. But today I did figure out something that was really giving me fits and I want to document it for later.

I wanted to start a new activity and in the view for that activity display a chart using the Android GraphView. Jonas provides nice documentation with example code on how to do this. But the fragment thing was really messing me up. I couldn’t figure out where to put the code and how to get it to work. The example I was interested in looks like this:

// init example series data
GraphViewSeries exampleSeries = new GraphViewSeries(new GraphViewData[] {
      new GraphViewData(1, 2.0d)
      , new GraphViewData(2, 1.5d)
      , new GraphViewData(3, 2.5d)
      , new GraphViewData(4, 1.0d)
});
 
GraphView graphView = new LineGraphView(
      this // context
      , "GraphViewDemo" // heading
);
graphView.addSeries(exampleSeries); // data
 
LinearLayout layout = (LinearLayout) findViewById(R.id.graph1);
layout.addView(graphView);

But I would put it in different places and crash the app or get compiler errors before I even started. I did a lot of searching and reading before I got it to work and I guess I don’t need to rehash all that. It was the accepted answer on this stackoverflow question that finally put the last piece in place for me though.

When I create a new activity the class for it has a class inside that creates the fragment:

public static class PlaceholderFragment extends Fragment {
 
        public PlaceholderFragment() {
        }
 
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            return rootView;
        }
    }

This made sense as the place to do my work but I couldn’t figure out how. I had trouble trying to reference the view. But it was right in front of me the whole time. Here is what finally worked.

public static class PlaceholderFragment extends Fragment {
 
        public PlaceholderFragment() {
 
        }
 
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_show_graph, container, false);
 
 
            //I cannot believe I finally figured this out.
            GraphViewSeries avSeries = new GraphViewSeries(new GraphView.GraphViewData[] {
                    new GraphView.GraphViewData(1, 223)
                    , new GraphView.GraphViewData(2, 221)
                    , new GraphView.GraphViewData(3, 220)
                    , new GraphView.GraphViewData(4, 221)
            });
 
            GraphView monthAverage = new LineGraphView(this.getActivity(), "Jan Data");
            monthAverage.addSeries(avSeries);
 
            LinearLayout layout = (LinearLayout)  rootView.findViewById(R.id.graphM);
            layout.addView(monthAverage);
            //this is the end of my part
 
            return rootView;
 
        }
 
    }

Oh – here’s the xml for the layout. I don’t think it matters a whole lot – but this is where the graphM id is located.

 xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    android:id="@+id/graphM"
    tools:context="org.pyrrhic.eatwatch.showGraph$PlaceholderFragment">
 
>

I was so happy when I ran this and I saw my graph pop up rather than the error message from the app crashing. It was a banner moment in my day.

Setting Up My AndroidStudio Project on GitHub

I started a project to do my homework for the week in the Android class I’m taking. I’ve been doing the bulk of my work on a desktop machine in my office. This week-end I also set up a dev environment on my Fedora laptop at home. I don’t want to have to monkey with copying files and carrying them back and forth so today I set up a GitHub repo so that I could use it to keep things in sync.

I’m no git expert. In the past what I’ve done is create a project in github with a couple pieces in place. Then I pull that down to a directory on my machine, add the files I need and then push all that back up.

Today I took a little bit of a different approach. I created the project. Then in bash I went to the root directory of the project and set things up. It took me a minute to get it all figured out. The git reference on remotes was a huge help. There is also the JetBrains documentation on git with IntelliJ which is what Android studio is built on.

For my own reference – once I got the project built I needed to add everything. First I went to github and made a repo – but I made it empty, not like I usually do. Then I went to the root of my project in bash.

git add .

and then make an initial commit

git commit -m 'initial commit'

I set up the remote

git remote add origin https://github.com/bittercode/learnandplay.git (bittercode is my github user name and learnandplay is the name of the repo I set up.)

Then I pushed the code to the remote

git push -u origin master

And that put it all up at github. Now I should be able to go home and pull it all down there. I also set up AndroidStudio so that it now handles all the git stuff. When I created a new activity it asked me about adding them to git – so I just said that it should default to yes and now I’m on the fast track to happy days.

Got a New Computer Today

I’ve been eagerly awaiting the arrival of my new Raspberry Pi and today it came. I was showing it to a co-worker and she was impressed that this little board is a computer. I really look forward to experimenting with it and seeing just what kind of creative uses we can come up with. I’m hoping it wont be long until they have them readily available and anyone who has a great idea for how to use them can get them in bulk.

Code Year / Codecademy (Edited)

A quick note – as Mike McGee points out in the comments – it is not Code Academy – it is Codecademy. My brain fixed the “error” without letting me know. It appears the Codecademy folks couldn’t get the name they wanted so went for something close. I apologize for any confusion my post may have created. — JR


The tldr – Very promising platform with a lot of potential, a bit rough around the edges right now.

Via TechCrunch, I found Codecademy. They are behind Code Year.

I’m not sure if the two are different at all. I guess I’ll figure it out when I get an email from Code Year. I’ve already done all the courses/lessons available at Codecademy.

Right now there is just some basic stuff on JavaScript. It’s not anything earth shattering – but I really like the approach and the platform they’ve built. All the lessons take place at their site. The lesson pages have instructions, an editor and a shell. Everything that one does happens in the editor or shell and it lets the student move on when each exercise is successfully completed.

There are some rough edges. Sometimes it’s necessary to read comments and instructions in the editor. The editor can’t be re-sized and a few times the comments were too long, so I had to scroll sideways to see the whole thing. That’s a pretty easy fix I think.

And sometimes I couldn’t get past an exercise but the feedback in the shell wouldn’t tell me why. I had one exercise where my solution was technically correct, but I’m guessing that the steps I took violated some threshold so it wouldn’t let me pass that section until I guessed just how they wanted it done. That was the most frustrating time so far. I could have skipped it and moved on but I wanted to get 100% completion.

They track how many lessons the student has passed. This leads to achievements that give students little badges on their profile. I really dig this kind of ‘gaming’ educational materials. I’m sure to certain people they are stupid or pointless – but to someone with a brain like mine they are incredibly motivating.

The Code Year piece is supposed to email out a new lesson each week. My guess is the first few weeks will be the lessons I’ve already done. I may blow off the code year thing and just keep checking code academy for new courses.

Performance as the Codecademy site has been less than stellar. I’m hoping they get that fixed. Sometimes I had to reload pages and pretty much always it was a long wait. Sometimes I’d finish a piece, it would show that I had completed it but then back at my profile it would show pieces not finished. I had to go back and click through the end again.

On an interesting side note – the Codecademy site says they are hiring. They are looking for a few people. What made me chuckle was the section on developers:
Our stack:

Backbone.js
Ruby/Rails
mongoDB
We love macs, but we’re not allergic to Linux systems

I laughed because I saw the Ruby on Rails bit and thought, “I wonder how that will scale.” They’ve been mentioned on TechCrunch and Hacker News already. I’m surprised if it hasn’t been submitted to Reddit. I expect to see it pop up on the slashdot front page at some point. I’m guessing they are going to see a lot of traffic.

Messing with App Inventor

I have been so busy I haven’t played with App Inventor in a long time. Yesterday I read an interesting article about MIT taking over the project. That got me wanting to get things set up again and see where it was at.

It was frustrating because I couldn’t get my phone to connect to the software. I was googling and wracking my brain to figure out the issue. I tried on multiple machines with multiple OS’s. After many hours a very simple solution to my problems finally crept into my brain. I went home, got another USB cable and all my problems went away. Annoying but I’m glad I got it figured out.

On a related note, the App Inventor software is run from the browser. One piece, the “Blocks Editor” is written in Java. So the browser downloads a jnlp file and it needs to be run. I was using Chrome. But when I told it to auto-open the file after downloading it wouldn’t give me a choice in what program did the opening. It was using the open-jdk (which the docs say not to use) and I couldn’t figure out how to get it to let me switch to the Oracle jdk. So I went to running it from Firefox, where I had no problem setting this up correctly. There is a lot I really like about Chrome, but when I want to get stuff done, I inevitably end up back on Firefox

Python, UnixODBC, MDBTools and Microsoft Access on Fedora 12

This is funny to me in light of my last post. I have installed UnixODBC, I installed the gui tool to manage it and then I installed MDBTools to allow me to connect to a JET database. (This is all on my Fedora 12 machine by the way for those just joining us.) The funny part is that the time I spent getting the gui tool was wasted as it wont work with the driver anyway, at least not the way I’ve set it up. Not sure why, not sure that I care. Here is what I did to get it to work. First I checked for the driver ( /usr/lib/libmdbodbc.so.0 in my case ). It was there so I edited /etc/odbcinst.ini and added the following entry.

[MDBToolsODBC]
Description = MDB Tools ODBC
Driver = /usr/lib/libmdbodbc.so.0
Setup =
FileUsage =
CPTimeout =
CPReuse =



That takes care of telling UnixODBC about the driver. I wonder if there is a file from MDBTools that I can use for the setup part. Not sure, may look into it at some point. The next step was creating a DSN. That involved adding the following lines to /etc/odbc.ini (Which existed but was empty because I hadn’t created any entries yet.)

[lintry]
Description = Microsoft Access Try DB
Driver = MDBToolsODBC
Database = /home/jr.peck/Documents/lintry.mdb
Servername = localhost
Username =
Password =
port = 5432




Here is what a connection in Python could look like.

import pyodbc


sql = 'Select * from foo'

conn = pyodbc.connect('DSN=lintry')
cursor = conn.cursor()
cursor.execute(sql)
rows = cursor.fetchall()

for record in rows:
    print record.FirstName + ' ' + record.LastName
  
cursor.close()
conn.close()



In my database the table foo contains three columns and the first two are FirstName and LastName. So anyone messing this will obviously need to change it to match their table name, column names, etc. This last piece of getting things to work on Linux wasn’t really necessary but it didn’t take all that long to figure out and I’m glad I did, in case I do need it down the road. I imagine this would work just the same for any other programming language that could take advantage of UnixODBC.

Fedora and UnixODBC

January of last year UnixODBC spun off non-core code to separate projects of their own. The reasoning they give on their site makes sense. I’m just not sure I follow all the ramifications when it comes to how this works out on the user level with different distros. What I do know is that with Fedora if one wants to use the gui ODBC manager, ODBCConfig, then that does not come in the unixODBC package – it comes in unixODBC-kde. What’s interesting is that over at their sourceforge file list it shows a GTK version but that doesn’t show up in my KPackageKit list. I’m not sure how that came to be and I’m not sure if I have time or the inclination to figure it out.

The thing that drives me to mention it at all is that if one is googling around looking for info. on how to use UnixODBC, they are going to come under the impression that ODBCConfig is part of that package. The reason I figured out to look for something else was I happened to google Fedora and UnixODBC and ran across a forum posting that put me on track.

Looking at the ODBCConfig page itself, with a last update over 10 years ago, I wonder if those goes back further than last year. I don’t know. I haven’t messed with UnixODBC in quite a while and last time I did it was on AIX and I was just concerned with MS SQL Server drivers. Now I’m trying to get my little Python program I wrote to read an MS Access database running on my Fedora machine. This is stupid in a sense as I’d never willingly use MS Access on a linux box but I just want to see if I can do it. It would make more sense to switch to SQLite.

So just to sum up – if you want to use UnixODBC on Fedora, with the gui admin tool, you need to install 2 packages rather than just one. Getting the drivers themselves is also another matter. My next task is to see if I can MDBTools and UnixODBC to play nice together. I’ve found examples from folks who say they’ve done it so I’m going to give it a whirl.