In this lab we'll add the buttons to the view complete with tests.
Note: They won't be pretty and they won't do anything!
As I build each key, I write a test. Then I add the next key. I typically don't start laying out the views or making them pretty until they are all present in the view and the tests are passing. I commit after the views are present. Then I do a styling commit afterward (we'll do that as a separate step).
Last we saw this file, we had all the initialization code in the the test that we wrote. Let's make a field for the fragment and move the initialization to the setUp()
function:
private ButtonFragment buttonFragment;
@Before
public void setUp() throws Exception
{
buttonFragment = new ButtonFragment();
startFragment( buttonFragment );
}
Now we can add a new test.
We use getView()
to get a reference to the view and then find the specific id.
@Test
public void shouldHaveOneKey() throws Exception
{
assertViewIsVisible( buttonFragment.getView()
.findViewById( R.id.key1 ) );
}
Now we add the button to the view.
<!--1-->
<Button
android:id="@+id/key1"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="5dp"
android:text="@string/key1"/>
It's best practice to move your strings to the strings.xml
file instead of leaving them hard coded in the view. It also makes it easier to test that the correct string is configured for a view.
<string name="key1">1</string>
The lint tool will recommend this for you by showing yellow bars and a light bulb in the view.
Let's extend our test to ensure that the correct string is configured for the view. We'll use our ResourceLocator
class to get the resource string and compare it to TextView
's getText()
return to ensure they are equal.
Our final test looks like this:
@Test
public void shouldHaveOneKey() throws Exception
{
TextView key1 = (TextView) buttonFragment.getView().findViewById( R.id.key1 );
assertViewIsVisible( key1 );
assertThat( key1.getText().toString(),
equalTo( ResourceLocator.getString( R.string.key1 ) ) );
}
Add each number and operator key in turn and make sure the tests pass along the way. After you're done with the buttons, commit.
Let's replace our parent LinearLayout
with a RelativeLayout
so that we can define the position of the buttons relative to the other buttons.
Please refer to the screenshot of the example project to determine where each button should be positioned.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<!--1-->
<Button
android:id="@+id/key1"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="5dp"
android:text="@string/key1"/>
<!--2-->
<Button
android:id="@+id/key2"
android:layout_toRightOf="@id/key1"
android:layout_alignBaseline="@id/key1"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="5dp"
android:text="@string/key2"/>
<!--3-->
<Button
android:id="@+id/key3"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="5dp"
android:layout_toRightOf="@id/key2"
android:layout_alignBaseline="@id/key2"
android:text="@string/key3"/>
<!--4-->
<Button
android:id="@+id/key4"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="5dp"
android:layout_below="@id/key1"
android:text="@string/key4"/>
...
</RelativeLayout>
Note: There are many ways this view could be laid out.
RelativeLayout
isn't the most intuitive choice, but it is quite useful and mastery of it early in your Android career will lead to great things.