Create a BeatBox app
1. In Android Studio, select the menu item File → New → New Project... To create a New Project. The project name is BeatBox
2. Create a new empty activity named BeatBoxActivity, and the other default items remain unchanged to complete the project creation.
3. First create the RecyclerView layout file. RES / layout / activity generated by the wizard_ beat_ box. XML is useless, so it is directly renamed fragment_beat box.xml. Then, modify the code to complete the layout definition
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent"/> </layout>
4. Now, on COM bignerdranch. android. In the beatbox package, create a new Fragment named BeatBoxFragment with the following code
public class BeatBoxFragment extends Fragment { public static BeatBoxFragment newInstance() { return new BeatBoxFragment(); }
5. Then, clear all contents in the BeatBoxActivity class, inherit the SingleFragmentActivity class instead, and override the createFragment() method
public class BeatBoxFragment extends Fragment( public static BeatBoxFragment newInstance()£ return new BeatBoxFragment()
Data binding
6. In the application of build Enable data binding in gradle file. The code is as follows.
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 {
7. Change the general layout to data binding layout
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler view" android:layout width=match parent" android:layout_height="match_parent"/> </layout>
8. Instantiate the 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()
9. Configure RecyclerView (BeatBoxFragment.java)
public class BeatBoxFragment extends Fragment f 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();
10. Next, create the button layout file 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>
11. Create SoundHolder (BeatBoxFragment.java)
public class Beatboreueament newinstance{ public static BeatBoxFragment newinstance(){ return new BeatBoxFragment() } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ private class SoundHolder extends RecyclerView.ViewHolder{ f private ListItemSoundBinding mBinding; private SoundHolder(ListItemSoundBinding binding) super{binding.getRoot()}; mBinding = binding; }
12. Create SoundAdapter(BeatBoxFragmentjava)
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); returnnew SoundHolder(binding); } @Override 20 public void onBindViewHolder(SoundHolder holder, int position){} @Override public intgetItemCount(){ return 0; } } }
13. Use SoundAdapter (BeatBoxFragmentjava)
@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() }
Import assets
14. First create the assets directory. Right click the app module and select New → Folder → AssetsFolder to pop up the screen as shown in the figure. Uncheck the Change Folder Location option and keep the Target Source
The main option of Set remains unchanged. Click Finish to finish.
Next, right-click the assets Directory and select the menu item New → Directory to create a sample for the sound resource_ Sounds sub
15. Download and unzip the voice file to the assets/sample sounds directory, as shown in the figure
Process assets
16. Create a new resource management class named BeatBox. The code is shown below on COM bignerdranch. android. Create this class in the BeatBox package and
Add two constants: one for logging and the other for storing the directory name of the sound resource file.
public class BeatBox { private static final String TAG ="BeatBox"; private static final String SOUNDS_FOLDER ="sample_sounds"; }
17. Add a constructor with Context parameter to obtain and retain it, as shown in the code
public class BeatBox { private static final String TAG ="BeatBox"; private static final String SOUNDS_FOLDER ="sample_sounds";private AssetManager mAssets; public BeatBox(Context context) { mAssets = context.getAssets(); } }
18. View assets resource (BeatBox.java)
public BeatBox(Context context) { mAssets = context.getAssets(); LoadSounds(); } private void loadSounds(){ String[] soundNames; try { soundNames = mAssets.list(SOUNDS_FOLDER); Log.i(TAG,"Found"+ soundNames.length +" sounds"); } catch (IOException ioe){ Log.e(TAG, "Could not list assets", ioe); return; } }
19. Create a BeatBox instance (BeatBoxFragmentjava)
public class BeatBoxFragment extends Fragment{ private BeatBox mBeatBox; public static BeatBoxFragment newInstance(){ return new BeatBoxFragment(); } @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); mBeatBox = new BeatBox(getActivity()); } }
Using assets
20. Create a Sound management class with the following code
public class Sound { private String mAssetPath; private String mName; public Sound(String assetPath) { mAssetPath = assetPath; String[] components = assetPath.split("/"); String filename = components [components.length - 1]; mName= filename.replace(".wav",""); } public String getAssetPath(){ return mAssetPath; } public String getName() { return mName; } }
21. Next, in beatbox Create a Sound list in the loadsounds() method
public class BeatBox { private AssetManager mAssets; private List<Sound> mSounds = new ArrayList>(); public BeatBox(Context context){ } private void loadSounds() { String[] soundNames; try { } catch(I0Exception ioe){ } for (String filename : soundNames){ String assetPath = SOUNDS_FOLDER +"/"+ filename; Sound sound = new Sound(assetPath); mSounds.add(sound); } } public List<Sound> getSounds(){ return mSounds; } }
22. Bind Sound list (BeatBoxFragment.java)
private class SoundAdapter extends RecyclerView.Adapter<SoundHolder> { private List<Sound> mSounds; public SoundAdapter(List<Sound> sounds) { mSounds = sounds; ...} @Override public void onBindViewHolder(SoundHolder soundHolder, int position){ } @Override public int getItemCount(){ return mSounds.size(); } }
Create view model
23. Create a new class named SoundViewModel, and then add two properties: a Sound object and a BeatBox object for playing Sound files. The code is as follows
public class SoundViewModel { private Sound mSound; private BeatBox mBeatBox; public SoundViewModel(BeatBox beatBox){ mBeatBox = beatBox; } public Sound getSound(){ return mSound; } public void setSound(Sound sound) { mSound = sound; } }
24. Add binding method (SoundViewModel.java)
public class SoundViewModel { private Sound mSound; private BeatBox mBeatBox; public SoundViewModel(BeatBox beatBox){ mBeatBox = beatBox; } public String getTitle(){ return mSound.getName(); } public Sound getSound(){ return mSound;
Bind to view model
25. Declare view model attributes (list item sound.xml)
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <data> <variable name="viewModel" type="com.bignerdranch.android.beatbox.SoundViewModel"/> </data> <Button
26. Bind button file name (list_item sound.xml)
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <data> <variable name="viewModel" type="com.bignerdranch.android.beatbox.SoundViewModel"/> </data> <Button android:layout width="match_parent" android:layout_height="120dp" android:text="@[viewModel.title]" tools:text="Sound name"/> </layout>
27. Associated view model (BeatBoxFragment.java)
private class SoundHolder extends RecyclerView.ViewHolder{ private listitemSoundBinding mBinding; private SoundHolder(listitemSoundBinding binding){ super(binding.getRoot()); mBinding = binding; mBinding.setViewModel(new SoundViewModel(mBeatBox)); } public void bind(Sound sound) { mBinding.getViewModel().setSound(sound); mBinding.executePendingBindings(); } }
28. Call bind(Sound) method (BeatBoxFragmentjava)
return new SoundHolder(binding); } @Override public void onBindViewHolder(SoundHolder holder, int position){ Sound sound = mSounds.get(position); holder.bind(sound); } @Override public int getitemCount(){ return mSounds.size(); }
29. The operation results are shown in the figure below