8
Displaying Lists with RecyclerView

CriminalIntent’s model layer currently consists of a single instance of Crime. In this chapter, you will update CriminalIntent to work with a list of crimes. The list will display each Crime’s title and date, as shown in Figure 8.1.

Figure 8.1  A list of crimes

Screenshot shows CriminalIntent in Android phone. The screen shows the list of Custom items in CriminalIntent app.

Figure 8.2 shows the overall plan for CriminalIntent in this chapter.

Figure 8.2  CriminalIntent with a list of crimes

Figure shows CriminalIntent with a list of crimes.

In the model layer, you have a new object, CrimeLab, that will be a centralized data stash for Crime objects.

Displaying a list of crimes requires a new activity and a new fragment in CriminalIntent’s controller layer: CrimeListActivity and CrimeListFragment.

(Where are CrimeActivity and CrimeFragment in Figure 8.2? They are part of the detail view, so we are not showing them here. In Chapter 10, you will connect the list and the detail parts of CriminalIntent.)

In Figure 8.2, you can also see the view objects associated with CrimeListActivity and CrimeListFragment. The activity’s view will consist of a fragment-containing FrameLayout. The fragment’s view will consist of a RecyclerView. You will learn more about the RecyclerView class later in the chapter.

Updating CriminalIntent’s Model Layer

The first step is to upgrade CriminalIntent’s model layer from a single Crime object to a List of Crime objects.

Singletons and centralized data storage

You are going to store the List of crimes in a singleton. A singleton is a class that allows only one instance of itself to be created.

A singleton exists as long as the application stays in memory, so storing the list in a singleton will keep the crime data available throughout any lifecycle changes in your activities and fragments. Be careful with singleton classes, as they will be destroyed when Android removes your application from memory. The CrimeLab singleton is not a solution for long-term storage of data, but it does allow the app to have one owner of the crime data and provides a way to easily pass that data between controller classes. (You will learn more about long-term data storage in Chapter 14.)

(See the For the More Curious section at the end of this chapter for more about singleton classes.)

To create a singleton, you create a class with a private constructor and a get() method. If the instance already exists, then get() simply returns the instance. If the instance does not exist yet, then get() will call the constructor to create it.

Right-click the com.bignerdranch.android.criminalintent package and choose NewJava Class. Name this class CrimeLab and click OK.

In CrimeLab.java, implement CrimeLab as a singleton with a private constructor and a get() method.

Listing 8.1  Setting up the singleton (CrimeLab.java)

public class CrimeLab {
    private static CrimeLab sCrimeLab;

    public static CrimeLab get(Context context) {
        if (sCrimeLab == null) {
            sCrimeLab = new CrimeLab(context);
        }
        return sCrimeLab;
    }

    private CrimeLab(Context context) {

    }
}

There are a few interesting things in this CrimeLab implementation. First, notice the s prefix on the sCrimeLab variable. You are using this Android convention to make it clear that sCrimeLab is a static variable.

Also, notice the private constructor on the CrimeLab. Other classes will not be able to create a CrimeLab, bypassing the get() method.

Finally, in the get() method on CrimeLab, you pass in a Context object. You will make use of this Context object in Chapter 14.

Let’s give CrimeLab some Crime objects to store. In CrimeLab’s constructor, create an empty List of Crimes. Also, add two methods: a getCrimes() method that returns the List and a getCrime(UUID) that returns the Crime with the given ID.

Listing 8.2  Setting up the List of Crime objects (CrimeLab.java)

public class CrimeLab {
    private static CrimeLab sCrimeLab;

    private List<Crime> mCrimes;

    public static CrimeLab get(Context context) {
        ...
    }

    private CrimeLab(Context context) {
        mCrimes = new ArrayList<>();
    }

    public List<Crime> getCrimes() {
        return mCrimes;
    }

    public Crime getCrime(UUID id) {
        for (Crime crime : mCrimes) {
            if (crime.getId().equals(id)) {
                return crime;
            }
        }

        return null;
    }
}

List<E> is an interface that supports an ordered list of objects of a given type. It defines methods for retrieving, adding, and deleting elements. A commonly used implementation of List is ArrayList, which uses a regular Java array to store the list elements.

Because mCrimes holds an ArrayList – and ArrayList is also a List – both ArrayList and List are valid types for mCrimes. In situations like this, we recommend using the interface type for the variable declaration: List. That way, if you ever need to use a different kind of List implementation – like LinkedList, for example – you can do so easily.

The mCrimes instantiation line uses diamond notation, <>, which was introduced in Java 7. This shorthand notation tells the compiler to infer the type of items the List will contain based on the generic argument passed in the variable declaration. Here, the compiler will infer that the ArrayList contains Crimes because the variable declaration private List<Crime> mCrimes; specifies Crime for the generic argument. (The more verbose equivalent, which developers were required to use prior to Java 7, is mCrimes = new ArrayList<Crime>();.)

Eventually, the List will contain user-created Crimes that can be saved and reloaded. For now, populate the List with 100 boring Crime objects.

Listing 8.3  Generating crimes (CrimeLab.java)

private CrimeLab(Context context) {
    mCrimes = new ArrayList<>();
    for (int i = 0; i < 100; i++) {
        Crime crime = new Crime();
        crime.setTitle("Crime #" + i);
        crime.setSolved(i % 2 == 0); // Every other one
        mCrimes.add(crime);
    }
}

Now you have a fully loaded model layer with 100 crimes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
107.20.123.227