Android Product Directory

PART 4: Return Data To MainActivity

When working with two activities, you can RETURN data from the second activity by packaging the data as intent extras similar to what you did when you sent data to the DetailActivity in the previous section. A constant is needed for each extra that is accessible to both the sender and the receiver that is used as the extra name that identifies its value.

Prep for Part 4

  1. Copy the ProductDirectoryAppPart3 and paste it in the same directory as ProductDirectoryAppPart4.
  2. Open ProductDirectoryAppPart4 in Android Studio.
  3. Right-click on the package and Refactor > Rename… and change the 3 to 4 on the package name: com.example.productdirectoryapppart4 and then click the OK button.
  4. In the strings.xml file change the 3 to 4 for the app name attribute:

    <string name="app_name">ProductDirectoryApp Part 4</string


  1. Open the Product Directory Part 4 Project and then open the MainActivity.
  2. Declare two new constants at the top of the MainActivity class:

    private static final int DETAIL_REQUEST = 333;
    public static final String RETURN_MESSAGE = "RETURN_MESSAGE";


    CODE EXPLANATION:
    - The first constant is private and will be used to coordinate the two activities. When the DetailActivity is launch, this request code will be passed and when it is returned from the DetailActivity, it will be seen again.
    - The second constant is public and will be a string that can be used as an extra name. It is set to public so that it can be visible to both activities (MainActivity and DetailActivity).

  3. Scroll down to OnItemClickListener() method for the listview and change the startActivity to startActivityForResult and then add an additional argument—the request code constant: DETAIL_REQUEST.

    listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    Intent intent = new Intent(MainActivity.this, DetailActivity.class);
    Product product = products.get(position);
    intent.putExtra(PRODUCT_ID, product.getProductId());
    startActivityForResult(intent, DETAIL_REQUEST);

    CODE EXPLANATION:
    - The OnItemClickListener() method is called when the user click on an item in the ListView.
    - Typically, the startActivity() method is used to launch an activity. However, to COORDINATE between two activities, you need to use the startActivityForResult() method instead. The intent object is passed to it as before, but an additional argument is also passed—the request code: DETAIL_REQUEST.

  4. (OPTIONAL) Open the activity_detail.xml file and change then email icon to a shopping cart icon.
  5. Open the DetailActivity class and add the word final in FRONT of the following code:

     final Product product = DataProvider.productMap.get(productId);

    NOTE: By making the variable final makes the code accessible to any code within an inner class.

    CODE EXPLANATION: By adding the word final to this variable makes it visible to any code within an inner class.

  6.  Delete the code for the Snackbar in the fab and replace it with the following highlighted code:

    fab_btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
      Intent data = new Intent();
    data.putExtra(MainActivity.RETURN_MESSAGE, product.getName() + " added to shopping cart");
    setResult(RESULT_OK, data);
    finish();

        }

    CODE EXPLANATION:
    - When a user clicks the fab button, a message will be send back from the DetailActivity to the MainActivity.
    - Notice the Intent() method did not pass an argument because it is only used to package data later with the putExtra() method.
    -  The data.putExtra is passed a constant that was created in the MainActivity class named RETURN_MESSAGE that is used to IDENTIFY the string that will be passed back. Then, a message is created with the product object and a string. You could use more than one extra.
    - In a production app, you could actually save this data in a persistent data store such as an SQL-like database. In this project, we are just sending the data back to the MainActivity.
    - The setResult() method is used to verify the result with the argument RESULT_OK which is a result code and the data.
    - The finish() method is used to close the current activity and return to the parent activity.

  7. Go to the activity_main.xml file and add and id of  coordinatorID to the end of the opening element:

    tools:context="com.example.productdirectoryapppart4.MainActivity"
    android:id="@+id/coordinatorID">

    NOTE:
    This will be used later in a SnackBar.

  8. Go back to the MainActivity class and add the following private statement to the top of the MainActivity method:

    private CoordinatorLayout coordinatorLayout;

  9. Inside of the onCreate() method, add the following highlighted code:

    setSupportActionBar(toolbar);
    coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorID);

    NOTE:
    This will be used for the Snackbar that will be created later.

  10. Insert the cursor BEFORE the last curly brace and type onActivity and press the ENTER key to complete the code below:

     @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    }

    }

    NOTE: This is an override of a superclass method.

  11. Delete the superclass statement and add the following two nested “if” statements:

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (requestCode == DETAIL_REQUEST) {
    if (resultCode == RESULT_OK) {
    String message = data.getStringExtra(RETURN_MESSAGE);
    // Toast.makeText(this, "test", Toast.LENGTH_SHORT).show();
    Snackbar.make(coordinatorLayout,message, Snackbar.LENGTH_LONG)
    .setAction("Action", null).show();
    }
    }

    }

    CODE EXPLANATION:
    - The OUTER “if” statement check the condition requestCode == DETAIL_REQUEST. The request code is being passed as the first argument and is checked against the constant used when the DetailActivity is requested the first time so it should be received back again. If this condition is true, the INNER “if” statement is used to check the result code (not request code) against a constant (RESULT_OK). If both conditions are true, the data can be processed.
    - A string variable named message is created and assigned a value from data.getStringExtra() method which is pass the RETURN_MESSAGE.
    - data is the third argument passed into the onActvityResult method to receive the data form the DetailActivity.
    - A Snackbar is used to display a message.

  12. CHECK POINT: Run the app in an emulator. Click on an item and you should be taken to the DetailActivity as before. Now, click on the fab button and you should be taken BACK to the ListView and see a SnackBar message displayed.
  13. (OPTIONAL) You could add some additional functionality to the Snackbar message by calling the setAction() method and REPLACING the “Action” and null arguments in the setAction() method with the following highlighted code:

    • a string (“Go to cart”)
    • an instance event listener interface (new View.OnClickListener). In the onClick() method that is generated, a Toast is used to tell the user that he or she is being taken to the shopping cart

      Snackbar.make(coordinatorLayout,message, Snackbar.LENGTH_LONG)
      .setAction("Go to cart", new View.OnClickListener() {
      @Override
      public void onClick(View v) {
      Toast.makeText(MainActivity.this,
      "Going to cart", Toast.LENGTH_SHORT).show();
      }
      }

              ).show();

  14. CHECK POINT: Run the app in an emulator. Click on an item and you should be taken to the DetailActivity as before. Now, click on the fab button and you should be taken BACK to the ListView and see a SnackBar message displayed. If you did the optional step, click the Go To Cart link, you should see the Toast Message. Instead of the message, you could create a shopping cart screen and add persistent data storage to your app to build a complete e-commerce app.