This probably isn’t really elegant, but it works. As described in a previous post, use a LinearLayout in fragment_beat_box.xml:
<LinearLayout
android:orientation="vertical"
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_weight="1"
android:layout_height="0dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginLeft="15dp"
android:id="@+id/playback_label"
android:text="@string/playback_label" />
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/playback_bar" />
</LinearLayout>
Then set up the new elements in BeatBoxFragment and add a few helper methods:
private FragmentBeatBoxBinding mBinding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_beat_box, container, false);
mBinding.recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
mBinding.recyclerView.setAdapter(new SoundAdapter(mBeatBox.getSounds()));
mBinding.playbackBar.setMax(150); //bar goes from 0 to 150, speed 50 to 200
setPlaybackSpeed(100);
showSpeed();
mBinding.playbackBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
Log.d(BeatBox.TAG, "progress value="+seekBar.getProgress());
showSpeed();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
return mBinding.getRoot();
}
//get speed (50 - 200)
public int getPlaybackSpeed() {
return mBinding.playbackBar.getProgress()+50;
}
//convert a speed to a bar position
private void setPlaybackSpeed(int speed) {
if (speed<50) speed = 50;
if (speed>200) speed = 200;
mBinding.playbackBar.setProgress(speed-50);
}
private void showSpeed() {
mBinding.playbackLabel.setText(getResources().getString(R.string.playback_label)+" "+getPlaybackSpeed()+"%");
mBeatBox.setPlaybackSpeed(getPlaybackSpeed());
}
Finally hook speed up to BeatBox
private int playbackSpeed;
public void setPlaybackSpeed(int speed) {
playbackSpeed = speed;
}
public void play(Sound sound) {
Integer soundId = sound.getSoundId();
if (soundId==null) return;
mSoundPool.play(soundId, 1.0f, 1.0f, 1, 0, playbackSpeed/100.0f);
}
I’m not really happy about all the funny value conversions in BeatBoxFragment, but wasn’t sure how to refactor. Any suggestions?
1 Like
ilya
April 7, 2017, 1:05am
2
(post withdrawn by author, will be automatically deleted in 24 hours unless flagged)
Maybe it’s help you
BeatBoxFragment.onCreateView
binding.seekBarText.setText("Playback Speed: 100%");
binding.seekBar.setProgress(binding.seekBar.getMax() / 2);
binding.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float result;
if (progress < seekBar.getMax() / 2) {
result = progress * 0.01f + 0.5f;
mBeatBox.setRate(result);
} else {
result = progress * 0.02f;
mBeatBox.setRate(result);
}
binding.seekBarText.setText("Playback Speed: " + (int)(result * 100) + "%");
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
BeatBox
private float mRate = 1.0f;
public void play(Sound sound) {
Integer soundId = sound.getSoundId();
if (soundId == null) {
return;
}
mSoundPool.play(soundId, 1.0f, 1.0f, 1, 0, mRate);
}
public void setRate(float rate) {
mRate = rate;
}
fragment_beat_box
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
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"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#FFFFFF">
<android.support.v7.widget.AppCompatSeekBar
android:id="@+id/seek_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/seek_bar_text"
/>
<TextView
android:id="@+id/seek_bar_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="8dp"/>
</RelativeLayout>
</FrameLayout>
</layout>
My solution is nearly the same to this one except I created a public global variable in BeatBox to set the play rate and used an if statement in the OnSeekBarChangeListener to avoid 0 division:
//SeekBar
binding.seekBarPlaySpeed.setProgress(100);
binding.seekBarPlaySpeed.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
binding.textViewSeekBarProgress.setText(getString(R.string.seek_bar_progress_text,Integer.toString(binding.seekBarPlaySpeed.getProgress())));
if(progress !=0){mBeatBox.mPlayRate = (float) progress/100;}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
how about this
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_beat_box, container, false);
mBinding.recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
mBinding.recyclerView.setAdapter(new SoundAdapter(mBeatBox.getSounds()));
mBinding.seekBarPlaySpeed.setMax(150);
mBinding.seekBarPlaySpeed.setProgress(75);
applyPlaybackSpeed();
mBinding.seekBarPlaySpeed.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int pos, boolean b) {
applyPlaybackSpeed();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) { }
@Override
public void onStopTrackingTouch(SeekBar seekBar) { }
});
return mBinding.getRoot();
}
private void applyPlaybackSpeed() {
float rate = (float) mBinding.seekBarPlaySpeed.getProgress() / mBinding.seekBarPlaySpeed.getMax() + 0.5f;
mBinding.playSpeedLabel.setText(String.format(getResources().getString(R.string.playback_label), Math.round(rate * 100)));
mBeatBox.setPlayRate(rate);
}