Creating BeatBox

Time to get started. The first step is to create your BeatBox app. In Android Studio, select FileNew Project... to create a new project. Call it BeatBox and give it a company domain of android.bignerdranch.com. Use API 19 for your minimum SDK and start with one Empty Activity called BeatBoxActivity. Leave the defaults as they are.

You will be using RecyclerView again, so open your project preferences and add the com.android.support:recyclerview-v7 dependency.

Now, let’s build out the basics of the app. The main screen will show a grid of buttons, each of which will play a sound. So, you will need two layout files: one for the grid and one for the buttons.

Create your layout file for the RecyclerView first. You will not need res/layout/activity_beat_box.xml, so go ahead and rename it fragment_beat_box.xml.

Open the newly renamed fragment_beat_box.xml. Delete the existing contents of the file. Then fill it up like so:

Listing 20.1  Reworking main layout file (res/layout/fragment_beat_box.xml)

<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Now create a new Fragment called BeatBoxFragment in com.bignerdranch.android.beatbox.

Listing 20.2  Creating BeatBoxFragment (BeatBoxFragment.java)

public class BeatBoxFragment extends Fragment {
    public static BeatBoxFragment newInstance() {
        return new BeatBoxFragment();
    }
}

For now, leave it empty.

Next, create the BeatBoxActivity your new fragment should go in. You will use the same SingleFragmentActivity architecture you used in CriminalIntent.

First, use your favorite file explorer or terminal application to copy SingleFragmentActivity.java from CriminalIntent into BeatBox/app/src/main/java/com/bignerdranch/android/beatbox/, and then copy activity_fragment.xml into BeatBox/app/src/main/res/layout/. (You can pull these files out of your own CriminalIntent folder or from the solutions. For information on how to access the solutions files, refer back to the section called Adding an Icon in Chapter 2.)

Next, delete everything in the body of BeatBoxActivity, change it to a subclass of SingleFragmentActivity, and override createFragment(), like so:

Listing 20.3  Filling out BeatBoxActivity (BeatBoxActivity.java)

public class BeatBoxActivity extends SingleFragmentActivity {
    @Override
    protected Fragment createFragment() {
        return BeatBoxFragment.newInstance();
    }
}

Simple data binding

The next job is to inflate fragment_beat_box.xml and hook up its RecyclerView. This is a job that you have done before. But this time, you will use data binding to speed up your work.

Start by enabling data binding in your app’s build.gradle file.

Listing 20.4  Enabling data binding (app/build.gradle)

        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
              'proguard-rules.pro'
        }
    }
    dataBinding {
        enabled = true
    }
}

dependencies {

This turns on the IDE integration that will allow you to access the classes data binding will generate for you and integrate that class generation into your build.

To use data binding within a particular layout file, you have to change it into a data binding layout file. The way you do that is by wrapping the entire XML file in a <layout> tag.

Listing 20.5  Wrapping it up (res/layout/fragment_beat_box.xml)

<layout
    xmlns:android="http://schemas.android.com/apk/res/android">
    <android.support.v7.widget.RecyclerView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</layout>

The <layout> tag is your signal to the data binding tool that it should get to work on your layout file. Once it is done, it will generate a binding class for you. By default, this class is named after your layout file, but instead of using snake_case, it is switched to CamelCase naming style.

Your fragment_beat_box.xml file has already generated a binding class, called FragmentBeatBoxBinding. This class is what you will use for data binding: Instead of inflating a view hierarchy with a LayoutInflater, you will inflate an instance of FragmentBeatBoxBinding. FragmentBeatBoxBinding will hold on to the view hierarchy for you in a getter called getRoot(). In addition to that, it holds on to named references for each view you tagged with an android:id in your layout file.

So your FragmentBeatBoxBinding class has two references: getRoot(), which refers to the entire layout, and recyclerView, which refers to just your RecyclerView (Figure 20.2).

Figure 20.2  Your binding class

Figure shows Binding class.

Your layout only has one view, of course, so both references point at the same view: your RecyclerView.

Now to use this binding class. Override onCreateView(…) in BeatBoxFragment and use DataBindingUtil to inflate an instance of FragmentBeatBoxBinding (Listing 20.6). (You will need to import FragmentBeatBoxBinding like any other class. If Android Studio cannot find FragmentBeatBoxBinding, this means it was not autogenerated for some reason. Force Android Studio to generate the class by selecting BuildRebuild Project. If the class is not generated after forcing the project to rebuild, restart Android Studio.)

Listing 20.6  Inflating a binding class (BeatBoxFragment.java)

public class BeatBoxFragment extends Fragment {
    public static BeatBoxFragment newInstance() {
        return new BeatBoxFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        FragmentBeatBoxBinding binding = DataBindingUtil
                .inflate(inflater, R.layout.fragment_beat_box, container, false);

        return binding.getRoot();
    }
}

With your binding created, you can now get at your RecyclerView and configure it.

Listing 20.7  Configuring RecyclerView (BeatBoxFragment.java)

public class BeatBoxFragment extends Fragment {
    public static BeatBoxFragment newInstance() {
        return new BeatBoxFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        FragmentBeatBoxBinding binding = DataBindingUtil
                .inflate(inflater, R.layout.fragment_beat_box, container, false);

        binding.recyclerView.setLayoutManager(new GridLayoutManager(getActivity(),
                                                                         3));

        return binding.getRoot();
    }
}

This is what we call simple data binding – using data binding to automatically pull out views for you, instead of writing findViewById(…). Later, you will see more advanced uses of data binding. For now, though, you will continue wiring up your RecyclerView.

Next, create the layout for the buttons, res/layout/list_item_sound.xml. You will be using data binding here, as well, so add a layout tag surrounding your layout file.

Listing 20.8  Creating sound layout (res/layout/list_item_sound.xml)

<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
    <Button
        android:layout_width="match_parent"
        android:layout_height="120dp"
        tools:text="Sound name"/>
</layout>

Next, create a SoundHolder wired up to list_item_sound.xml.

Listing 20.9  Creating SoundHolder (BeatBoxFragment.java)

public class BeatBoxFragment extends Fragment {
    public static BeatBoxFragment newInstance() {
        return new BeatBoxFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ...
    }

    private class SoundHolder extends RecyclerView.ViewHolder {
        private ListItemSoundBinding mBinding;

        private SoundHolder(ListItemSoundBinding binding) {
            super(binding.getRoot());
            mBinding = binding;
        }
    }
}

Your SoundHolder expects the binding class you just implicitly created: ListItemSoundBinding.

Next, create an Adapter hooked up to SoundHolder. (If you put your cursor on RecyclerView.Adapter before typing in any of the methods below and hit Option+Return [Alt+Enter], Android Studio will enter most of this code for you.)

Listing 20.10  Creating SoundAdapter (BeatBoxFragment.java)

public class BeatBoxFragment extends Fragment {
    ...
    private class SoundHolder extends RecyclerView.ViewHolder {
        ...
    }

    private class SoundAdapter extends RecyclerView.Adapter<SoundHolder> {
        @Override
        public SoundHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(getActivity());
            ListItemSoundBinding binding = DataBindingUtil
                    .inflate(inflater, R.layout.list_item_sound, parent, false);
            return new SoundHolder(binding);
        }

        @Override
        public void onBindViewHolder(SoundHolder holder, int position) {

        }

        @Override
        public int getItemCount() {
            return 0;
        }
    }
}

Now wire up SoundAdapter in onCreateView(…).

Listing 20.11  Wiring up SoundAdapter (BeatBoxFragment.java)

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    FragmentBeatBoxBinding binding = DataBindingUtil
            .inflate(inflater, R.layout.fragment_beat_box, container, false);

    binding.recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
    binding.recyclerView.setAdapter(new SoundAdapter());

    return binding.getRoot();
}
..................Content has been hidden....................

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