Seeing This In Action

As the name suggests, the TwoActivities sample module in the Sampler and SamplerJ projects has two activities. The MainActivity is very similar to the Toolbar one from the previous chapter. However, now when the user clicks on a color, we want to launch a second activity that shows that color in a larger form.

The Second Activity

The second activity is named BigSwatchActivity, and it was created using the “Empty Activity” template in the Android Studio new-activity wizard. As a result, the wizard added a manifest entry for our activity… the same one shown previously in this chapter:

    <activity android:name=".BigSwatchActivity"></activity>

The new-activity wizard created an activity_big_swatch layout resource, which we modified to have a Toolbar at the top and a View taking up all the remaining space:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".BigSwatchActivity">

  <androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:theme="?attr/actionBarPopupTheme"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

  <View
    android:id="@+id/swatch"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@id/toolbar" />

</androidx.constraintlayout.widget.ConstraintLayout>

And, the new-activity wizard created the BigSwatchActivity class itself, which we then augmented with actual app logic. That class could be written in Java:

package com.commonsware.jetpack.samplerj.activities;

import android.os.Bundle;
import com.commonsware.jetpack.samplerj.activities.databinding.ActivityBigSwatchBinding;
import androidx.appcompat.app.AppCompatActivity;

public class BigSwatchActivity extends AppCompatActivity {
  static final String EXTRA_COLOR = "color";

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ActivityBigSwatchBinding binding =
      ActivityBigSwatchBinding.inflate(getLayoutInflater());

    setContentView(binding.getRoot());

    int color = getIntent().getIntExtra(EXTRA_COLOR, 0x7FFF0000);

    binding.toolbar.setTitle("#" + Integer.toHexString(color));
    binding.swatch.setBackgroundColor(color);
  }
}

…or Kotlin:

package com.commonsware.jetpack.sampler.activities

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.commonsware.jetpack.sampler.activities.databinding.ActivityBigSwatchBinding

const val EXTRA_COLOR = "color"

class BigSwatchActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val color = intent.getIntExtra(EXTRA_COLOR, 0x7FFF0000)

    ActivityBigSwatchBinding.inflate(layoutInflater).apply {
      setContentView(root)
      toolbar.title = "#${Integer.toHexString(color)}"
      swatch.setBackgroundColor(color)
    }
  }
}

First, we call setContentView(R.layout.activity_big_swatch) to load up our layout resource.

Then, we need to know what color to display. This activity expects to receive that color in the form of an Intent extra. We have an EXTRA_COLOR constant defined to use as the key. We call getIntent() to retrieve the Intent that created the activity, and on that we call getIntExtra() to retrieve the EXTRA_COLOR value. The get...Extra() functions that return primitives, like an Int, take two parameters: the key to use to find the extra, and the default value to return if the extra is not found. In our case, we use a hard-coded gray value as the default.

Then, we:

In the case of the Kotlin code, we take advantage of the fact that we only need the binding inside of onCreate() to use the apply() scope function and skip any sort of property declaration.

Starting the Activity

However, this activity will never be shown to the user unless we call startActivity() at some point to show it, ideally passing the desired color as the EXTRA_COLOR extra.

The Toolbar sample app — building on previous ones — handles row clicks in ColorViewHolder. So, this app just changes ColorViewHolder to start BigSwatchActivity instead of showing a Toast:

package com.commonsware.jetpack.samplerj.activities;

import android.content.Context;
import android.content.Intent;
import android.view.View;
import com.commonsware.jetpack.samplerj.activities.databinding.RowBinding;
import androidx.recyclerview.widget.RecyclerView;

class ColorViewHolder extends RecyclerView.ViewHolder {
  private final RowBinding row;
  private int color;

  ColorViewHolder(RowBinding row) {
    super(row.getRoot());

    this.row = row;
    row.getRoot().setOnClickListener(this::showBigSwatch);
  }

  void bindTo(Integer color) {
    this.color = color;

    row.label.setText(
      row.label.getContext().getString(R.string.label_template, color));
    row.swatch.setBackgroundColor(color);
  }

  private void showBigSwatch(View v) {
    Context context = v.getContext();

    context.startActivity(new Intent(context, BigSwatchActivity.class)
      .putExtra(BigSwatchActivity.EXTRA_COLOR, color));
  }
}
package com.commonsware.jetpack.sampler.activities

import android.content.Intent
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.commonsware.jetpack.sampler.activities.databinding.RowBinding

class ColorViewHolder(private val row: RowBinding) :
  RecyclerView.ViewHolder(row.root) {
  private var color: Int = 0x7FFFFFFF

  init {
    row.root.setOnClickListener(this::showBigSwatch)
  }

  fun bindTo(color: Int) {
    this.color = color
    row.label.text = row.label.context.getString(R.string.label_template, color)
    row.swatch.setBackgroundColor(color)
  }

  private fun showBigSwatch(v: View) {
    val context = v.context

    context.startActivity(
      Intent(context, BigSwatchActivity::class.java)
        .putExtra(EXTRA_COLOR, color)
    )
  }
}

We use a method reference to tie our row clicks to a showBigSwatch() method. There, we:

Now, when the user taps on a color in the list, we see the BigSwatchActivity, showing a very large color swatch that probably does not match our Toolbar color very well:

TwoActivities Sample, Showing BigSwatchActivity
TwoActivities Sample, Showing BigSwatchActivity

Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.