MP1_CalebFontenot
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package com.bignerdranch.android.beatbox;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.bignerdranch.android.beatbox" >
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name=".BeatBoxActivity"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,78 @@
|
||||
package com.bignerdranch.android.beatbox;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.content.res.AssetManager;
|
||||
import android.media.AudioManager;
|
||||
import android.media.SoundPool;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BeatBox {
|
||||
private static final String TAG = "BeatBox";
|
||||
|
||||
private static final String SOUNDS_FOLDER = "sample_sounds";
|
||||
private static final int MAX_SOUNDS = 5;
|
||||
|
||||
private AssetManager mAssets;
|
||||
private List<Sound> mSounds;
|
||||
private SoundPool mSoundPool;
|
||||
|
||||
public BeatBox(Context context) {
|
||||
mAssets = context.getAssets();
|
||||
// This old constructor is deprecated, but we need it for
|
||||
// compatibility.
|
||||
//noinspection deprecation
|
||||
mSoundPool = new SoundPool(MAX_SOUNDS, AudioManager.STREAM_MUSIC, 0);
|
||||
loadSounds();
|
||||
}
|
||||
|
||||
public void play(Sound sound) {
|
||||
Integer soundId = sound.getSoundId();
|
||||
if (soundId == null) {
|
||||
return;
|
||||
}
|
||||
mSoundPool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f);
|
||||
}
|
||||
|
||||
public void release() {
|
||||
mSoundPool.release();
|
||||
}
|
||||
|
||||
public List<Sound> getSounds() {
|
||||
return mSounds;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
mSounds = new ArrayList<Sound>();
|
||||
for (String filename : soundNames) {
|
||||
try {
|
||||
String assetPath = SOUNDS_FOLDER + "/" + filename;
|
||||
Sound sound = new Sound(assetPath);
|
||||
load(sound);
|
||||
mSounds.add(sound);
|
||||
} catch (IOException ioe) {
|
||||
Log.e(TAG, "Could not load sound " + filename, ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void load(Sound sound) throws IOException {
|
||||
AssetFileDescriptor afd = mAssets.openFd(sound.getAssetPath());
|
||||
int soundId = mSoundPool.load(afd, 1);
|
||||
sound.setSoundId(soundId);
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
package com.bignerdranch.android.beatbox;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
|
||||
public class BeatBoxActivity extends SingleFragmentActivity {
|
||||
|
||||
@Override
|
||||
protected Fragment createFragment() {
|
||||
return BeatBoxFragment.newInstance();
|
||||
}
|
||||
}
|
@@ -0,0 +1,136 @@
|
||||
package com.bignerdranch.android.beatbox;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.app.Fragment;
|
||||
import android.graphics.Point;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BeatBoxFragment extends Fragment {
|
||||
|
||||
private BeatBox mBeatBox;
|
||||
private View mRedFill;
|
||||
|
||||
public static BeatBoxFragment newInstance() {
|
||||
return new BeatBoxFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
|
||||
mBeatBox = new BeatBox(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_beat_box, container, false);
|
||||
|
||||
mRedFill = view.findViewById(R.id.red_fill);
|
||||
mRedFill.setVisibility(View.INVISIBLE);
|
||||
|
||||
RecyclerView recyclerView = (RecyclerView)view
|
||||
.findViewById(R.id.recycler_view);
|
||||
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
|
||||
recyclerView.setAdapter(new SoundAdapter(mBeatBox.getSounds()));
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mBeatBox.release();
|
||||
}
|
||||
|
||||
private class SoundHolder extends RecyclerView.ViewHolder
|
||||
implements View.OnClickListener {
|
||||
private Button mButton;
|
||||
private Sound mSound;
|
||||
|
||||
public SoundHolder(LayoutInflater inflater, ViewGroup parent) {
|
||||
super(inflater.inflate(R.layout.list_item_sound, parent, false));
|
||||
|
||||
mButton = (Button)itemView.findViewById(R.id.button);
|
||||
mButton.setOnClickListener(this);
|
||||
}
|
||||
|
||||
public void bindSound(Sound sound) {
|
||||
mSound = sound;
|
||||
mButton.setText(mSound.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int[] clickCoords = new int[2];
|
||||
v.getLocationOnScreen(clickCoords);
|
||||
|
||||
clickCoords[0] += (v.getWidth() / 2);
|
||||
clickCoords[1] += (v.getHeight() / 2);
|
||||
|
||||
performRevealAnimation(mRedFill, clickCoords[0], clickCoords[1]);
|
||||
mBeatBox.play(mSound);
|
||||
}
|
||||
}
|
||||
|
||||
private void performRevealAnimation(final View view, int screenCenterX, int screenCenterY) {
|
||||
int[] animatingViewCoords = new int[2];
|
||||
view.getLocationOnScreen(animatingViewCoords);
|
||||
int centerX = screenCenterX - animatingViewCoords[0];
|
||||
int centerY = screenCenterY - animatingViewCoords[1];
|
||||
|
||||
Point size = new Point();
|
||||
getActivity().getWindowManager().getDefaultDisplay().getSize(size);
|
||||
int maxRadius = size.y;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
view.setVisibility(View.VISIBLE);
|
||||
Animator animator = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, 0, maxRadius);
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
view.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
}
|
||||
}
|
||||
|
||||
private class SoundAdapter extends RecyclerView.Adapter<SoundHolder> {
|
||||
private List<Sound> mSounds;
|
||||
|
||||
public SoundAdapter(List<Sound> sounds) {
|
||||
mSounds = sounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
|
||||
LayoutInflater inflater = LayoutInflater.from(getActivity());
|
||||
return new SoundHolder(inflater, viewGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(SoundHolder soundHolder, int i) {
|
||||
Sound sound = mSounds.get(i);
|
||||
soundHolder.bindSound(sound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mSounds.size();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package com.bignerdranch.android.beatbox;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
public abstract class SingleFragmentActivity extends AppCompatActivity {
|
||||
protected abstract Fragment createFragment();
|
||||
|
||||
protected int getLayoutResId() {
|
||||
return R.layout.activity_fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(getLayoutResId());
|
||||
FragmentManager manager = getFragmentManager();
|
||||
Fragment fragment = manager.findFragmentById(R.id.fragmentContainer);
|
||||
|
||||
if (fragment == null) {
|
||||
fragment = createFragment();
|
||||
manager.beginTransaction()
|
||||
.add(R.id.fragmentContainer, fragment)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package com.bignerdranch.android.beatbox;
|
||||
|
||||
public class Sound {
|
||||
private String mAssetPath;
|
||||
private String mName;
|
||||
private Integer mSoundId;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public Integer getSoundId() {
|
||||
return mSoundId;
|
||||
}
|
||||
|
||||
public void setSoundId(Integer soundId) {
|
||||
mSoundId = soundId;
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/button_beat_box_pressed"
|
||||
android:state_pressed="true"/>
|
||||
<item android:drawable="@drawable/button_beat_box_normal" />
|
||||
</selector>
|
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
|
||||
<solid
|
||||
android:color="@color/dark_blue"/>
|
||||
</shape>
|
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape
|
||||
android:shape="oval">
|
||||
|
||||
<solid
|
||||
android:color="@color/red"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape
|
||||
android:shape="oval">
|
||||
|
||||
<stroke
|
||||
android:width="4dp"
|
||||
android:color="@color/dark_red"/>
|
||||
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/fragmentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
@@ -0,0 +1,17 @@
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/red_fill"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/red"/>
|
||||
|
||||
</FrameLayout>
|
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:layout_gravity="center"
|
||||
tools:text="Sound name"/>
|
||||
</FrameLayout>
|
@@ -0,0 +1,9 @@
|
||||
<menu 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"
|
||||
tools:context=".BeatBoxActivity">
|
||||
<item android:id="@+id/action_settings"
|
||||
android:title="@string/action_settings"
|
||||
android:orderInCategory="100"
|
||||
app:showAsAction="never"/>
|
||||
</menu>
|
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
@@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
||||
(such as screen margins) for screens with more than 820dp of available width. This
|
||||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
||||
<dimen name="activity_horizontal_margin">64dp</dimen>
|
||||
</resources>
|
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="red">#F44336</color>
|
||||
<color name="dark_red">#C3352B</color>
|
||||
<color name="gray">#607D8B</color>
|
||||
<color name="soothing_blue">#0083BF</color>
|
||||
<color name="dark_blue">#005A8A</color>
|
||||
</resources>
|
@@ -0,0 +1,5 @@
|
||||
<resources>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
</resources>
|
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="app_name">BeatBox</string>
|
||||
<string name="hello_world">Hello world!</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
|
||||
</resources>
|
@@ -0,0 +1,16 @@
|
||||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="Theme.AppCompat">
|
||||
<item name="colorPrimary">@color/red</item>
|
||||
<item name="colorPrimaryDark">@color/dark_red</item>
|
||||
<item name="colorAccent">@color/gray</item>
|
||||
|
||||
<item name="android:colorBackground">@color/soothing_blue</item>
|
||||
<item name="android:buttonStyle">@style/BeatBoxButton</item>
|
||||
</style>
|
||||
|
||||
<style name="BeatBoxButton" parent="android:style/Widget.Holo.Button">
|
||||
<item name="android:background">@drawable/button_beat_box</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
Reference in New Issue
Block a user