Skip to content

Latest commit

 

History

History
213 lines (174 loc) · 6.56 KB

10-2-M-Develop-Android-Part-1.adoc

File metadata and controls

213 lines (174 loc) · 6.56 KB

Developing for Android: Part 1

Developing the View Layout

In the next steps, we will develop a simple GUI as the view for the mobile EventRegistration app with (1) one text field for specifying the name of a person, and (2) one Add Person button

The GUI will look like as depicted below.
Simple GUI

  1. Open the content_main.xml file, which contains a default Hello World text.

  2. Replace the highlighted default content with the following XML tags.
    Android Hello World

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/error"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:visibility="gone"
            android:text=""
            android:textColor="#FF0000"/>

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/newperson_name"
            android:hint="@string/newperson_hint"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:text="@string/newperson_button"
            android:onClick="addPerson"/>
    </LinearLayout>
  • LinearLayout declares a vertical layout to hold the GUI elements;

  • EditText adds a textfield to enter the name of the person;

  • Button provides a button to add a person.

    Some erroneous tags are marked in red, which will be corrected in the following steps.

Specifying a text field and a button
  1. We place new literals in the strings.xml

    <string name="newperson_hint">Who?</string>
    <string name="newperson_button">Add Person</string>
  2. Save strings.xml

Observing the view
  1. Save the file content_main.xml.

  2. Click on the Design tab to check the graphical preview of the app.

    Graphical content view

Connecting to backend via RESTful service calls

As a next step, we define a view depicted below and add Java code to provide behavior for the view, e.g. what should happen when the different buttons are clicked. The key interactions of our application are the following:

  1. What to do when the application is launched? (onCreate())

  2. What to do when a button is clicked? (addPerson())

Create a utility class for communicating with HTTP messages
  1. Make sure you have the implementation 'com.loopj.android:android-async-http:1.4.9' dependency (among others) in the build.gradle file for the app module (see the section on project setup for more details)

  2. Create the HttpUtils class in the ca.mcgill.ecse321.eventregistration package and add missing imports as required with Alt+Enter

    Tip
    You may need to wait a few minutes after dependencies have been resolved to allow the IDE to index classes
    public class HttpUtils {
        public static final String DEFAULT_BASE_URL = "https://eventregistration-backend-123.herokuapp.com/";
    
        private static String baseUrl;
        private static AsyncHttpClient client = new AsyncHttpClient();
    
        static {
            baseUrl = DEFAULT_BASE_URL;
        }
    
        public static String getBaseUrl() {
            return baseUrl;
        }
    
        public static void setBaseUrl(String baseUrl) {
            HttpUtils.baseUrl = baseUrl;
        }
    
        public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
            client.get(getAbsoluteUrl(url), params, responseHandler);
        }
    
        public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
            client.post(getAbsoluteUrl(url), params, responseHandler);
        }
    
        public static void getByUrl(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
            client.get(url, params, responseHandler);
        }
    
        public static void postByUrl(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
            client.post(url, params, responseHandler);
        }
    
        private static String getAbsoluteUrl(String relativeUrl) {
            return baseUrl + relativeUrl;
        }
    }
Further helper methods
  1. Open the MainActivity.java file.

  2. Add a new attribute to the beginning of the class for error handling.

    // ...
    public class MainActivity extends AppCompatActivity {
      private String error = null;
    
      // ...
    }
  3. Implement the refreshErrorMessage() method to display the error message on the screen, if there is any.

    Note
    Again, add imports with Alt+Enter (import is needed for TextView)
    private void refreshErrorMessage() {
      // set the error message
      TextView tvError = (TextView) findViewById(R.id.error);
      tvError.setText(error);
    
      if (error == null || error.length() == 0) {
        tvError.setVisibility(View.GONE);
      } else {
        tvError.setVisibility(View.VISIBLE);
      }
    }
  4. Add code to initialize the application in the onCreate() method (after the auto-generated code).

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      // ...
      // INSERT TO END OF THE METHOD AFTER AUTO-GENERATED CODE
      // initialize error message text view
      refreshErrorMessage();
    }
Creating a handler for Add Person button
  1. Implement the addPerson() method as follows

    public void addPerson(View v) {
      error = "";
      final TextView tv = (TextView) findViewById(R.id.newperson_name);
      HttpUtils.post("persons/" + tv.getText().toString(), new RequestParams(), new JsonHttpResponseHandler() {
          @Override
          public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
              refreshErrorMessage();
              tv.setText("");
          }
          @Override
          public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
              try {
                  error += errorResponse.get("message").toString();
              } catch (JSONException e) {
                  error += e.getMessage();
              }
              refreshErrorMessage();
          }
      });
    }
  2. Import the missing classes again with Alt+Enter. There are multiple Header classes available, you need to import the cz.msebera.android.httpclient.Header class.