I was originally thinking I would talk about inheritance in this blog entry but I decided to step it up a notch and talk about something more interesting. I will be breaking the content up between two or three blogs as it will be fairly in depth.
Any one who has been programming in Android recently, probably knows fragments are a necessity if you want to have cool looking UI’s on multiple devices but If your new to Android and have not used fragments or simply don’t get them, this blog/tutorial might help you. Fragments were introduced back in February of 2011 with the release of Android 3.0 so this is not a brand new topic but its a crucial one and so here it goes.
Fragments allow you the developer to have separate sub activities within your current activity and essentially host multiple independent UI’s on the same screen. They are great for displaying multiple activities at once on larger tablets and you can even replace existing fragments with other fragments on the fly. That means you no longer need to have an activity for every page. Sort of any way. A single activity lets say running on a phone for instance, so it is only displaying one fragment at a time, can switch fragments in and out as it needs them; but realize that “fragment” is just a clever name for a sub activity so every fragment still must be hosted by an activity. If your developing in Android you will want to get comfortable with fragments so you can have a professional looking app, regardless of what device its being run on.
There are two ways android allows you to use fragment in your XML file. You can hard code a fragments into a your page layout or you can create FrameLayout and then add fragments late using code. The second option, using a FrameLayout, allows you to not only add but also replace fragments on the fly using code. Taking this approach will provide you much more flexibility and so its the approach I will be showing using code from my most recent project.
Here is the rafter_output.xml file from my Rafter Maker project.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:baselineAligned="false" android:orientation="horizontal" > <FrameLayout android:id="@+id/fragmenta" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="7" /> <FrameLayout android:id="@+id/fragmentb" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="3" /> </LinearLayout>
Notice at line 6 the orientation is set to horizontal and then on lines 12 and 18 I have applied a weight to each FrameLayout. This will divide the screen real-estate amongst each fragment accordingly when we load them in later. Something worth mentioning here is how weights are calculated, only because in my opinion the process is a bit counter intuitive. One would think that if fragmentA has a weight of 2 and fragmentB has a weight of 1 that we add them together to get 3 and then divide the weight of either fragment by that 3 to get the percentage it occupies on screen Meaning fragmentA would get 66% and fragmentB gets 33% but that is not the case, its actually the reverse. FragmentB will only occupy 66% while fragmentA will occupies the other 33%. Why it works that way I could not say.
Now next I will show the xml page layouts that we will be displaying in the fragments, which will eventually get loaded into our FrameLayouts. Below is a simplified version of my fragment_rafter_output.xml file. They original has many more rows of data which is why I choses to use a TableLayout as the root of the xml page.
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tableLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:layout_marginLeft="10dp" android:background="@color/theme_secondary_color" > <TableRow android:id="@+id/tableRow1" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Angle A = " android:textAppearance="?android:attr/textAppearanceLarge" android:textSize="20sp" /> <TextView android:id="@+id/tva" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0" android:textAppearance="?android:attr/textAppearanceLarge" android:textColor="@color/text_color" android:textSize="20sp" /> </TableRow> </TableLayout>
Now here we have my fragment_image_output.xml. file. I’ll show the whole file because most of it will become relevant as we move on.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/RootView"> <View android:layout_width="10dp" android:layout_height="fill_parent" android:background="@drawable/shadow_left" /> <LinearLayout android:id="@+id/llbuttons" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginLeft="10dp" android:layout_marginRight="5dp" android:layout_marginBottom="5dp" android:orientation="horizontal" > <Button android:id="@+id/bback" style="@style/ButtonText" android:layout_weight="2.5" android:background="@drawable/btn_blue" android:text="<" /> <Button android:id="@+id/bcreate" style="@style/ButtonText" android:layout_weight="1" android:background="@drawable/btn_blue" android:text="create" /> <Button android:id="@+id/bnext" style="@style/ButtonText" android:layout_weight="2.5" android:background="@drawable/btn_blue" android:text=">" /> </LinearLayout> <TextView android:id="@+id/tvStep" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:text="data" android:textSize="20sp" android:textStyle="bold" /> <FrameLayout android:id="@+id/flimage" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/tvStep" android:layout_above="@id/llbuttons"> <ImageView android:id="@+id/ivInstImage" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout> </RelativeLayout>
The first thing I want to point out is a small added bonus. If you look at lines 7-10 you will notice a View which sets a background gradient called shadow which is 10 dp wide and is the height of the page. This will make the page to its left appear closer to the user and add an element of depth to your app. The other thing to notice is the three buttons. We will be using those later to update our fragments. The last thing to notice is the FrameLayout containing our ImageView. When we click the next or back button a new rafter image will be loaded and the data fragment will be updated accordingly as well.
Well, that takes care of the XML layouts we will need, the next part to handle will be the the code that defines our fragments and our host activity in Java.
Till then,
Jason Hintlian
From the blog jasonhintlian » cs-wsu by jasonhintlian and used with permission of the author. All other rights reserved by the author.