Compare commits

..

2 Commits

Author SHA1 Message Date
Loch Christian (uib05376)
9cad2f20f1 Implement delayed average, add delay SeekBar, add clear button 2020-11-11 20:53:03 +01:00
Loch Christian (uib05376)
28b0f2aae3 Add SeekBar value labels 2020-11-11 18:49:41 +01:00
3 changed files with 271 additions and 34 deletions

View File

@ -17,6 +17,7 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
public static final int defaultTrackLength = 100; public static final int defaultTrackLength = 100;
public static final float defaultBrakeProb = 0.3f; public static final float defaultBrakeProb = 0.3f;
public static final float defaultMaxVelocity = 5.0f; public static final float defaultMaxVelocity = 5.0f;
public static final int defaultDelay = 0;
protected Track track; protected Track track;
protected TimeRecordView trackView; protected TimeRecordView trackView;
protected Worker worker; protected Worker worker;
@ -26,21 +27,41 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
this.track = new Track(defaultNoOfVehicles, defaultTrackLength, defaultBrakeProb, defaultMaxVelocity); this.track = new Track(defaultNoOfVehicles, defaultTrackLength, defaultBrakeProb,
defaultMaxVelocity, defaultDelay);
this.track.addObserver(this); this.track.addObserver(this);
this.viewStack = (LinearLayout) findViewById(R.id.trackViewStack); this.viewStack = (LinearLayout) findViewById(R.id.trackViewStack);
SeekBar trackLengthSeekBar = (SeekBar) findViewById(R.id.trackLengthSeekBar); SeekBar trackLengthSeekBar = (SeekBar) findViewById(R.id.trackLengthSeekBar);
trackLengthSeekBar.setOnSeekBarChangeListener(this); trackLengthSeekBar.setOnSeekBarChangeListener(this);
trackLengthSeekBar.setProgress(defaultTrackLength); trackLengthSeekBar.setProgress(defaultTrackLength);
((TextView)(findViewById(R.id.trackLengthTextView))).setText(String.valueOf(defaultTrackLength));
SeekBar maxVelocitySeekBar = (SeekBar) findViewById(R.id.maxVelocitySeekBar); SeekBar maxVelocitySeekBar = (SeekBar) findViewById(R.id.maxVelocitySeekBar);
maxVelocitySeekBar.setOnSeekBarChangeListener(this); maxVelocitySeekBar.setOnSeekBarChangeListener(this);
maxVelocitySeekBar.setProgress((int)defaultMaxVelocity); maxVelocitySeekBar.setProgress((int)defaultMaxVelocity);
((TextView)(findViewById(R.id.maxVeloTextView))).setText(String.valueOf((int)defaultMaxVelocity));
SeekBar noOfVehiclesSeekBar = (SeekBar) findViewById(R.id.noOfVehiclesSeekBar); SeekBar noOfVehiclesSeekBar = (SeekBar) findViewById(R.id.noOfVehiclesSeekBar);
noOfVehiclesSeekBar.setOnSeekBarChangeListener(this); noOfVehiclesSeekBar.setOnSeekBarChangeListener(this);
noOfVehiclesSeekBar.setProgress(defaultNoOfVehicles); noOfVehiclesSeekBar.setProgress(defaultNoOfVehicles);
((TextView)(findViewById(R.id.noOfVehiclesTextView))).setText(String.valueOf(defaultNoOfVehicles));
SeekBar brakeProbabilitySeekBar = (SeekBar) findViewById(R.id.brakeProbabilitySeekBar); SeekBar brakeProbabilitySeekBar = (SeekBar) findViewById(R.id.brakeProbabilitySeekBar);
brakeProbabilitySeekBar.setOnSeekBarChangeListener(this); brakeProbabilitySeekBar.setOnSeekBarChangeListener(this);
brakeProbabilitySeekBar.setProgress((int)(defaultBrakeProb*20)); brakeProbabilitySeekBar.setProgress((int)(defaultBrakeProb*20));
((TextView)(findViewById(R.id.brakeProbTextView))).setText(String.valueOf(defaultBrakeProb));
SeekBar delaySeekBar = (SeekBar)(findViewById(R.id.simDelaySeekBar));
delaySeekBar.setOnSeekBarChangeListener(this);
delaySeekBar.setProgress(defaultDelay);
this.update(this.track, null);
}
public static float round(float number, int digits) {
float div = (float) Math.pow(10.0f, digits);
return Math.round(number*div)/div;
} }
@Override @Override
@ -50,6 +71,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
final MainActivity mainActivity = this; final MainActivity mainActivity = this;
final TextView lastAvgView = (TextView) findViewById(R.id.avgVeloLastView); final TextView lastAvgView = (TextView) findViewById(R.id.avgVeloLastView);
final TextView overallAvgView = (TextView) findViewById(R.id.avgVeloOverallView); final TextView overallAvgView = (TextView) findViewById(R.id.avgVeloOverallView);
final TextView delayedAvgView = (TextView) findViewById(R.id.delayedAvgTextView);
final TextView stepsView = (TextView) findViewById(R.id.stepsTextView);
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -57,8 +80,11 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
if (viewStackRef.getChildCount() > 0) if (viewStackRef.getChildCount() > 0)
viewStackRef.removeViewAt(0); viewStackRef.removeViewAt(0);
viewStackRef.addView(newTrView); viewStackRef.addView(newTrView);
lastAvgView.setText(String.valueOf(trackRef.getLastAvg())); lastAvgView.setText(String.valueOf(round(trackRef.getLastAvg(), 2)));
overallAvgView.setText(String.valueOf(trackRef.getOverallAvg())); overallAvgView.setText(String.valueOf(round(trackRef.getOverallAvg(), 2)));
stepsView.setText(String.valueOf(trackRef.getVtrList().size()));
delayedAvgView.setText(String.valueOf(round(trackRef.getDelayedAvg(), 2)));
} }
}); });
} }
@ -74,6 +100,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
stepButton.setEnabled(false); stepButton.setEnabled(false);
Button stopButton = (Button) findViewById(R.id.stopButton); Button stopButton = (Button) findViewById(R.id.stopButton);
stopButton.setEnabled(true); stopButton.setEnabled(true);
Button clearButton = (Button) findViewById(R.id.clearButton);
clearButton.setEnabled(false);
this.worker = new Worker(track); this.worker = new Worker(track);
this.worker.start(); this.worker.start();
@ -86,6 +114,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
stepButton.setEnabled(true); stepButton.setEnabled(true);
Button stopButton = (Button) findViewById(R.id.stopButton); Button stopButton = (Button) findViewById(R.id.stopButton);
stopButton.setEnabled(false); stopButton.setEnabled(false);
Button clearButton = (Button) findViewById(R.id.clearButton);
clearButton.setEnabled(true);
this.worker.setStop(true); this.worker.setStop(true);
try { try {
@ -96,6 +126,31 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
this.worker = null; this.worker = null;
} }
protected void stopWorker() {
this.worker.setStop(true);
try {
this.worker.join();
} catch (InterruptedException ex) {
}
this.worker = null;
}
public void onClearButtonClick(View view) {
this.track.deleteObserver(this);
if (this.worker != null) { // There was a simulation running
this.stopWorker();
}
Button playButton = (Button) findViewById(R.id.playButton);
playButton.setEnabled(true);
Button stepButton = (Button) findViewById(R.id.stepButton);
stepButton.setEnabled(true);
Button stopButton = (Button) findViewById(R.id.stopButton);
stopButton.setEnabled(false);
this.updateTrack();
this.update(this.track, null);
}
protected void updateTrack() { protected void updateTrack() {
int newTrackLength = ((SeekBar)(findViewById(R.id.trackLengthSeekBar))).getProgress(); int newTrackLength = ((SeekBar)(findViewById(R.id.trackLengthSeekBar))).getProgress();
SeekBar noOfVehiclesSeekBar = (SeekBar)(findViewById(R.id.noOfVehiclesSeekBar)); SeekBar noOfVehiclesSeekBar = (SeekBar)(findViewById(R.id.noOfVehiclesSeekBar));
@ -103,18 +158,24 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
if (newTrackLength < newNoOfVehicles) { // Dont allow values greater than track length! if (newTrackLength < newNoOfVehicles) { // Dont allow values greater than track length!
newNoOfVehicles = (int) newTrackLength; newNoOfVehicles = (int) newTrackLength;
noOfVehiclesSeekBar.setProgress(newNoOfVehicles); noOfVehiclesSeekBar.setProgress(newNoOfVehicles);
} }
TextView noOfVehiclesTextView = (TextView)(findViewById(R.id.noOfVehiclesTextView));
noOfVehiclesTextView.setText(String.valueOf(newNoOfVehicles));
TextView trackLengthTextView = (TextView)(findViewById(R.id.trackLengthTextView));
trackLengthTextView.setText(String.valueOf(newTrackLength));
float newMaxVelocity = ((SeekBar) findViewById(R.id.maxVelocitySeekBar)).getProgress(); float newMaxVelocity = ((SeekBar) findViewById(R.id.maxVelocitySeekBar)).getProgress();
SeekBar brakeProbabilitySeekBar = (SeekBar) findViewById(R.id.brakeProbabilitySeekBar); SeekBar brakeProbabilitySeekBar = (SeekBar) findViewById(R.id.brakeProbabilitySeekBar);
float newBrakeProb = (float)brakeProbabilitySeekBar.getProgress() / (float)brakeProbabilitySeekBar.getMax(); float newBrakeProb = (float)brakeProbabilitySeekBar.getProgress() / (float)brakeProbabilitySeekBar.getMax();
this.track = new Track(newNoOfVehicles, newTrackLength, newBrakeProb, newMaxVelocity);
int newDelay = ((SeekBar)(findViewById(R.id.simDelaySeekBar))).getProgress();
this.track = new Track(newNoOfVehicles, newTrackLength, newBrakeProb, newMaxVelocity, newDelay);
this.track.addObserver(this); this.track.addObserver(this);
if (this.worker != null) { // There was a simulation running already if (this.worker != null) { // There was a simulation running already
this.worker.setStop(true); this.stopWorker();
try {
this.worker.join();
} catch (InterruptedException ex) {
}
this.worker = new Worker(track); this.worker = new Worker(track);
this.worker.start(); this.worker.start();
} }
@ -126,12 +187,19 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
this.updateTrack(); this.updateTrack();
} else if (seekBar == (SeekBar)(findViewById(R.id.brakeProbabilitySeekBar))) { } else if (seekBar == (SeekBar)(findViewById(R.id.brakeProbabilitySeekBar))) {
float newBrakeProb = (float)seekBar.getProgress() / (float)seekBar.getMax(); float newBrakeProb = (float)seekBar.getProgress() / (float)seekBar.getMax();
System.out.println(newBrakeProb);
this.track.setBrakeProb(newBrakeProb); this.track.setBrakeProb(newBrakeProb);
TextView newBrakeProbTextView = (TextView)(findViewById(R.id.brakeProbTextView));
newBrakeProbTextView.setText(String.valueOf((newBrakeProb)));
} else if (seekBar == (SeekBar)(findViewById(R.id.maxVelocitySeekBar))) { } else if (seekBar == (SeekBar)(findViewById(R.id.maxVelocitySeekBar))) {
this.track.setMaxVelocity(seekBar.getProgress()); this.track.setMaxVelocity(seekBar.getProgress());
TextView tv = (TextView)(findViewById(R.id.maxVeloTextView));
tv.setText(String.valueOf(progress));
} else if (seekBar == (SeekBar)(findViewById(R.id.trackLengthSeekBar))) { } else if (seekBar == (SeekBar)(findViewById(R.id.trackLengthSeekBar))) {
this.updateTrack(); this.updateTrack();
} else if (seekBar == (SeekBar)(findViewById(R.id.simDelaySeekBar))) {
TextView tv = (TextView)(findViewById(R.id.simDelayTextView));
tv.setText(String.valueOf(seekBar.getProgress()));
this.track.setWaitTime(seekBar.getProgress());
} }
} }

View File

@ -10,22 +10,23 @@ public class Track extends Observable {
protected List<List<VehicleTimeRecord>> vtrList; protected List<List<VehicleTimeRecord>> vtrList;
protected float trackLength; protected float trackLength;
protected float sumAvgMemory; protected float sumAvgMemory;
protected float sumDelAvgMemory;
protected int historyLength; protected int historyLength;
protected float overallAvg; protected float overallAvg;
protected float delayedAvg;
protected float lastAvg; protected float lastAvg;
protected int waitTime; protected int waitTime;
protected float maxVelocity; protected float maxVelocity;
protected float brakeProb; protected float brakeProb;
public List<List<VehicleTimeRecord>> getVtrList() { public List<List<VehicleTimeRecord>> getVtrList() { return vtrList; }
return vtrList;
}
public float getOverallAvg() { public float getOverallAvg() {
return overallAvg; return overallAvg;
} }
public float getLastAvg() { public float getLastAvg() {
return lastAvg; return lastAvg;
} }
public float getDelayedAvg() { return delayedAvg; }
public List<Vehicle> getVehicles() { public List<Vehicle> getVehicles() {
return vehicles; return vehicles;
} }
@ -33,16 +34,19 @@ public class Track extends Observable {
return trackLength; return trackLength;
} }
public Track(int numberVehicles, float trackLength, float brakeProb, float maxVelocity) { public Track(int numberVehicles, float trackLength, float brakeProb, float maxVelocity, int waitTime) {
this.trackLength = trackLength; this.trackLength = trackLength;
this.brakeProb = brakeProb; this.brakeProb = brakeProb;
this.maxVelocity = maxVelocity; this.maxVelocity = maxVelocity;
this.vehicles = createVehiclesList(numberVehicles); this.vehicles = createVehiclesList(numberVehicles);
this.vtrList = new LinkedList<>(); this.vtrList = new LinkedList<>();
this.sumAvgMemory = 0; this.sumAvgMemory = 0;
this.sumDelAvgMemory = 0;
this.overallAvg = 0; this.overallAvg = 0;
this.delayedAvg = 0;
this.lastAvg = 0; this.lastAvg = 0;
this.historyLength = 25; this.historyLength = 25;
this.waitTime = waitTime;
} }
@ -56,6 +60,10 @@ public class Track extends Observable {
return result; return result;
} }
public void setWaitTime(int waitTime) {
this.waitTime = waitTime;
}
public void setBrakeProb(float brakeProb) { public void setBrakeProb(float brakeProb) {
for (Vehicle v : this.vehicles) { for (Vehicle v : this.vehicles) {
v.setBrakeProb(brakeProb); v.setBrakeProb(brakeProb);
@ -108,8 +116,13 @@ public class Track extends Observable {
protected void update_avg(){ protected void update_avg(){
lastAvg = avg_step(vtrList.size()-1); lastAvg = avg_step(vtrList.size()-1);
if (this.vtrList.size() > 10) {
sumDelAvgMemory += lastAvg;
delayedAvg = sumDelAvgMemory / (vtrList.size() - 10);
}
sumAvgMemory += lastAvg; sumAvgMemory += lastAvg;
overallAvg = sumAvgMemory / vtrList.size(); overallAvg = sumAvgMemory / vtrList.size();
} }
public float avg_span(int start, int end){ public float avg_span(int start, int end){

View File

@ -32,11 +32,25 @@
android:paddingTop="8dp" android:paddingTop="8dp"
android:paddingBottom="8dp"> android:paddingBottom="8dp">
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/textView4"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent">
android:text="Track length" />
<TextView
android:id="@+id/textView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Track length"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/trackLengthTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<SeekBar <SeekBar
android:id="@+id/trackLengthSeekBar" android:id="@+id/trackLengthSeekBar"
@ -47,11 +61,25 @@
android:min="1" android:min="1"
android:progress="50" /> android:progress="50" />
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/textView3"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent">
android:text="Number of vehicles" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Number of vehicles"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/noOfVehiclesTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<SeekBar <SeekBar
android:id="@+id/noOfVehiclesSeekBar" android:id="@+id/noOfVehiclesSeekBar"
@ -62,11 +90,24 @@
android:min="1" android:min="1"
android:progress="3" /> android:progress="3" />
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/textView5"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent">
android:text="Maximum velocity" />
<TextView
android:id="@+id/textView5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Maximum velocity"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/maxVeloTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="@+id/textView5" />
</androidx.constraintlayout.widget.ConstraintLayout>
<SeekBar <SeekBar
android:id="@+id/maxVelocitySeekBar" android:id="@+id/maxVelocitySeekBar"
@ -76,11 +117,24 @@
android:max="10" android:max="10"
android:progress="3" /> android:progress="3" />
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/textView6"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent">
android:text="Brake probability" />
<TextView
android:id="@+id/brakeProbLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Brake probability"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/brakeProbTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="@+id/brakeProbLabel" />
</androidx.constraintlayout.widget.ConstraintLayout>
<SeekBar <SeekBar
android:id="@+id/brakeProbabilitySeekBar" android:id="@+id/brakeProbabilitySeekBar"
@ -105,6 +159,29 @@
android:paddingTop="8dp" android:paddingTop="8dp"
android:paddingBottom="8dp"> android:paddingBottom="8dp">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Steps" />
<TextView
android:id="@+id/textView9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" " />
<TextView
android:id="@+id/stepsTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0" />
</TableRow>
<TableRow <TableRow
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@ -115,10 +192,17 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Average velocity (overall):" /> android:text="Average velocity (overall):" />
<TextView
android:id="@+id/textView10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" " />
<TextView <TextView
android:id="@+id/avgVeloOverallView" android:id="@+id/avgVeloOverallView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
android:text="0.0" />
</TableRow> </TableRow>
<TableRow <TableRow
@ -131,13 +215,43 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Average velocity (last step):" /> android:text="Average velocity (last step):" />
<TextView
android:id="@+id/textView11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" " />
<TextView <TextView
android:id="@+id/avgVeloLastView" android:id="@+id/avgVeloLastView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
android:text="0.0" />
</TableRow> </TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delayed average velocity:" />
<TextView
android:id="@+id/textView13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" " />
<TextView
android:id="@+id/delayedAvgTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0.0" />
</TableRow>
</TableLayout> </TableLayout>
<View <View
@ -155,14 +269,47 @@
<LinearLayout <LinearLayout
android:id="@+id/trackViewStack" android:id="@+id/trackViewStack"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="500dp"
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/linearLayout"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="8dp"> tools:layout_editor_absoluteX="8dp">
</LinearLayout> </LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/linearLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delay:" />
<SeekBar
android:id="@+id/simDelaySeekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:max="1000"
android:min="0"
app:layout_constraintEnd_toStartOf="@+id/simDelayTextView"
app:layout_constraintStart_toEndOf="@+id/textView6"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/simDelayTextView"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:gravity="right"
android:text="0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout <LinearLayout
android:id="@+id/linearLayout" android:id="@+id/linearLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -198,6 +345,15 @@
android:onClick="onStopButtonClick" android:onClick="onStopButtonClick"
android:text="Stop" /> android:text="Stop" />
<Button
android:id="@+id/clearButton"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="onClearButtonClick"
android:text="clear" />
</LinearLayout> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>