Added pager so we can swipe between fragments - only have two dummy fragments so far though - need to port the original mainActivity display components to separate fragments next.

This commit is contained in:
Graham Jones
2023-08-31 21:02:00 +01:00
parent baf679489a
commit d2577c1e0e
9 changed files with 477 additions and 21 deletions

View File

@@ -0,0 +1,57 @@
package uk.org.openseizuredetector;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.utils.ValueFormatter;
import java.text.DecimalFormat;
import java.util.ArrayList;
public class FragmentHrAlg extends FragmentSdDataViewer {
String TAG = "FragmentOsdAlg";
public FragmentHrAlg() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_osdalg, container, false);
}
@Override
protected void updateUi() {
Log.d(TAG,"updateUi()");
TextView tv;
tv = (TextView)mRootView.findViewById(R.id.fragment_osdalg_tv1);
if (mConnection.mBound) {
tv.setText("Bound to Server");
} else {
tv.setText("****NOT BOUND TO SERVER***");
return;
}
}
}

View File

@@ -1,11 +1,30 @@
package uk.org.openseizuredetector; package uk.org.openseizuredetector;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.core.content.res.ResourcesCompat;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.utils.ValueFormatter;
import java.text.DecimalFormat;
import java.util.ArrayList;
public class FragmentOsdAlg extends FragmentSdDataViewer { public class FragmentOsdAlg extends FragmentSdDataViewer {
String TAG = "FragmentOsdAlg";
public FragmentOsdAlg() { public FragmentOsdAlg() {
// Required empty public constructor // Required empty public constructor
} }
@@ -22,4 +41,156 @@ public class FragmentOsdAlg extends FragmentSdDataViewer {
// Inflate the layout for this fragment // Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_osdalg, container, false); return inflater.inflate(R.layout.fragment_osdalg, container, false);
} }
@Override
protected void updateUi() {
Log.d(TAG,"updateUi()");
TextView tv;
tv = (TextView)mRootView.findViewById(R.id.fragment_osdalg_tv1);
if (mConnection.mBound) {
tv.setText("Bound to Server");
} else {
tv.setText("****NOT BOUND TO SERVER***");
return;
}
/////////////////////////////////////////////////////
// Set ProgressBars to show margin to alarm.
long powerPc;
if (mConnection.mSdServer.mSdData.alarmThresh != 0)
powerPc = mConnection.mSdServer.mSdData.roiPower * 100 /
mConnection.mSdServer.mSdData.alarmThresh;
else
powerPc = 0;
long specPc;
if (mConnection.mSdServer.mSdData.specPower != 0 &&
mConnection.mSdServer.mSdData.alarmRatioThresh != 0)
specPc = 100 * (mConnection.mSdServer.mSdData.roiPower * 10 /
mConnection.mSdServer.mSdData.specPower) /
mConnection.mSdServer.mSdData.alarmRatioThresh;
else
specPc = 0;
long specRatio;
if (mConnection.mSdServer.mSdData.specPower != 0) {
specRatio = 10 * mConnection.mSdServer.mSdData.roiPower /
mConnection.mSdServer.mSdData.specPower;
} else
specRatio = 0;
((TextView)mRootView.findViewById(R.id.powerTv)).setText(getString(R.string.PowerEquals) + mConnection.mSdServer.mSdData.roiPower +
" (" + getString(R.string.Threshold) + "=" + mConnection.mSdServer.mSdData.alarmThresh + ")");
ProgressBar pb;
Drawable pbDrawable;
pb = ((ProgressBar) mRootView.findViewById(R.id.powerProgressBar));
pb.setMax(100);
pb.setProgress((int) powerPc);
pbDrawable = mRootView.getResources().getDrawable(R.drawable.progress_bar_blue);
if (powerPc > 75)
pbDrawable = mRootView.getResources().getDrawable(R.drawable.progress_bar_yellow);
if (powerPc > 100)
pbDrawable = mRootView.getResources().getDrawable(R.drawable.progress_bar_red);
pb.setProgressDrawable(pbDrawable);
((TextView)mRootView.findViewById(R.id.spectrumTv)).setText(getString(R.string.SpectrumRatioEquals) + specRatio +
" (" + getString(R.string.Threshold) + "=" + mConnection.mSdServer.mSdData.alarmRatioThresh + ")");
pb = ((ProgressBar) mRootView.findViewById(R.id.spectrumProgressBar));
pb.setMax(100);
pb.setProgress((int) specPc);
pbDrawable = mRootView.getResources().getDrawable(R.drawable.progress_bar_blue);
if (specPc > 75)
pbDrawable = mRootView.getResources().getDrawable(R.drawable.progress_bar_yellow);
if (specPc > 100)
pbDrawable = mRootView.getResources().getDrawable(R.drawable.progress_bar_red);
pb.setProgressDrawable(pbDrawable);
////////////////////////////////////////////////////////////
// Produce graph
BarChart mChart = (BarChart) mRootView.findViewById(R.id.chart1);
mChart.setDrawBarShadow(false);
mChart.setNoDataTextDescription("You need to provide data for the chart.");
mChart.setDescription("");
// X and Y Values
ArrayList<String> xVals = new ArrayList<String>();
ArrayList<BarEntry> yBarVals = new ArrayList<BarEntry>();
for (int i = 0; i < 10; i++) {
xVals.add(i + "-" + (i + 1) + " Hz");
if (mConnection.mSdServer != null) {
yBarVals.add(new BarEntry(mConnection.mSdServer.mSdData.simpleSpec[i], i));
} else {
yBarVals.add(new BarEntry(i, i));
}
}
// create a dataset and give it a type
BarDataSet barDataSet = new BarDataSet(yBarVals, "Spectrum");
try {
int[] barColours = new int[10];
for (int i = 0; i < 10; i++) {
if ((i < mConnection.mSdServer.mSdData.alarmFreqMin) ||
(i > mConnection.mSdServer.mSdData.alarmFreqMax)) {
barColours[i] = Color.GRAY;
} else {
barColours[i] = Color.RED;
}
}
barDataSet.setColors(barColours);
} catch (NullPointerException e) {
Log.e(TAG, "Null pointer exception setting bar colours");
}
barDataSet.setBarSpacePercent(20f);
barDataSet.setBarShadowColor(Color.WHITE);
BarData barData = new BarData(xVals, barDataSet);
barData.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float v) {
DecimalFormat format = new DecimalFormat("####");
return format.format(v);
}
});
mChart.setData(barData);
// format the axes
XAxis xAxis = mChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setTextSize(10f);
xAxis.setDrawAxisLine(true);
xAxis.setDrawLabels(true);
// Note: the default text colour is BLACK, so does not show up on black background!!!
// This took a lot of finding....
xAxis.setTextColor(Color.WHITE);
xAxis.setDrawGridLines(false);
YAxis yAxis = mChart.getAxisLeft();
yAxis.setAxisMinValue(0f);
yAxis.setAxisMaxValue(3000f);
yAxis.setDrawGridLines(true);
yAxis.setDrawLabels(true);
yAxis.setTextColor(Color.WHITE);
yAxis.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float v) {
DecimalFormat format = new DecimalFormat("#####");
return format.format(v);
}
});
YAxis yAxis2 = mChart.getAxisRight();
yAxis2.setDrawGridLines(false);
try {
mChart.getLegend().setEnabled(false);
} catch (NullPointerException e) {
Log.e(TAG, "Null Pointer Exception setting legend");
}
mChart.invalidate();
}
} }

View File

@@ -1,19 +1,29 @@
package uk.org.openseizuredetector; package uk.org.openseizuredetector;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;
/**
* A simple {@link Fragment} subclass.
* Use the {@link FragmentSdDataViewer#newInstance} factory method to
* create an instance of this fragment.
*/
public class FragmentSdDataViewer extends Fragment { public class FragmentSdDataViewer extends Fragment {
String TAG = "FragmentSdDataViewer";
Context mContext;
OsdUtil mUtil;
SdServiceConnection mConnection;
final Handler updateUiHandler = new Handler();
Timer mUiTimer;
protected View mRootView;
public FragmentSdDataViewer() { public FragmentSdDataViewer() {
@@ -23,7 +33,14 @@ public class FragmentSdDataViewer extends Fragment {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Log.i(TAG,"onCreate()");
mContext = getContext();
mUtil = new OsdUtil(mContext, updateUiHandler);
mConnection = new SdServiceConnection(mContext);
} }
@Override @Override
@@ -32,4 +49,78 @@ public class FragmentSdDataViewer extends Fragment {
// Inflate the layout for this fragment // Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_sd_data_viewer, container, false); return inflater.inflate(R.layout.fragment_sd_data_viewer, container, false);
} }
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRootView = view;
}
@Override
public void onStart() {
super.onStart();
Log.i(TAG, "onStart()");
if (mUtil.isServerRunning()) {
Log.i(TAG, "onStart() - Binding to Server");
mUtil.bindToServer(mContext, mConnection);
} else {
Log.i(TAG, "onStart() - Server Not Running");
}
}
@Override
public void onResume() {
super.onResume();
Log.i(TAG, "onResume()");
mUiTimer = new Timer();
mUiTimer.schedule(new TimerTask() {
@Override
public void run() {
updateUiOnUiThread();
}
}, 0, 1000);
}
@Override
public void onPause() {
super.onPause();
Log.i(TAG, "onPause()");
mUiTimer.cancel();
}
@Override
public void onStop() {
super.onStop();
Log.i(TAG, "onStop()");
mUtil.unbindFromServer(mContext, mConnection);
}
/**
* If we don't use this .post() trick, we get errors about the wrong thread trying to
* update the user interface views...
*/
private void updateUiOnUiThread() {
updateUiHandler.post(new Runnable(){
@Override
public void run() {
updateUi();
}
});
}
/**
* The subclasses should override this to draw their own UI.
*/
protected void updateUi() {
Log.d(TAG,"updateUi()");
TextView tv;
tv = (TextView)mRootView.findViewById(R.id.fragment_sddata_viewer_tv1);
if (mConnection.mBound) {
tv.setText("Bound to Server");
} else {
tv.setText("****NOT BOUND TO SERVER***");
}
}
} }

View File

@@ -1,20 +1,72 @@
package uk.org.openseizuredetector; package uk.org.openseizuredetector;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
public class MainActivity2 extends AppCompatActivity { public class MainActivity2 extends AppCompatActivity {
private String TAG = "MainActivity2";
private ViewPager2 mFragmentPager;
private FragmentStateAdapter mFragmentStateAdapter;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2); setContentView(R.layout.activity_main2);
if (savedInstanceState == null) { if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction() // Instantiate a ViewPager2 and a PagerAdapter.
.setReorderingAllowed(true) mFragmentPager = findViewById(R.id.fragment_pager);
.add(R.id.fragment_container_view, FragmentOsdAlg.class, null) mFragmentStateAdapter = new ScreenSlideFragmentPagerAdapter(this);
.commit(); mFragmentPager.setAdapter(mFragmentStateAdapter);
//getSupportFragmentManager().beginTransaction()
// .setReorderingAllowed(true)
// .add(R.id.fragment_container_view, FragmentOsdAlg.class, null)
// .commit();
}
}
@Override
public void onBackPressed() {
if (mFragmentPager.getCurrentItem() == 0) {
// If the user is currently looking at the first step, allow the system to handle the
// Back button. This calls finish() on this activity and pops the back stack.
super.onBackPressed();
} else {
// Otherwise, select the previous step.
mFragmentPager.setCurrentItem(mFragmentPager.getCurrentItem() - 1);
}
}
/**
* A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in
* sequence.
*/
private class ScreenSlideFragmentPagerAdapter extends FragmentStateAdapter {
private String TAG = "ScreenSlideFragmentPagerAdapter";
public ScreenSlideFragmentPagerAdapter(FragmentActivity fa) {
super(fa);
}
@Override
public Fragment createFragment(int position) {
switch(position) {
case 0:
return new FragmentOsdAlg();
case 1:
return new FragmentHrAlg();
default:
Log.e(TAG,"createFragment() - invalid Position "+position);
return null;
}
}
@Override
public int getItemCount() {
return 2;
} }
} }
} }

View File

@@ -6,11 +6,16 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity2"> tools:context=".MainActivity2">
<androidx.fragment.app.FragmentContainerView <!--<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container_view" android:id="@+id/fragment_container_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
/> />
-->
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -34,7 +34,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="View Error Log" android:text="View Error Log"
android:textColor="#212121"/> android:textColor="#212121"
android:visibility="gone"/>
<Button <Button
android:id="@+id/button_copy_error_log" android:id="@+id/button_copy_error_log"
@@ -42,7 +43,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:text="Copy Error Log" android:text="Copy Error Log"
android:textColor="#212121"/> android:textColor="#212121"
android:visibility="gone"/>
<Button <Button
android:id="@+id/button_share_error_log" android:id="@+id/button_share_error_log"
@@ -50,7 +52,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:text="Share Error Log" android:text="Share Error Log"
android:textColor="#212121"/> android:textColor="#212121"
android:visibility="gone"/>
<Button <Button
android:id="@+id/button_email_error_log" android:id="@+id/button_email_error_log"
@@ -66,7 +69,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:text="Save Error Log" android:text="Save Error Log"
android:textColor="#212121"/> android:textColor="#212121"
android:visibility="gone"/>
<Button <Button
android:id="@+id/button_close_app" android:id="@+id/button_close_app"

View File

@@ -0,0 +1,28 @@
<?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_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentSdDataViewer">
<!-- TODO: Update blank fragment layout -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="253dp"
android:orientation="vertical">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/fragment_hr_alg_tv1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Fragment_HrAlg" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="HR Algorithm Status" />
</androidx.appcompat.widget.LinearLayoutCompat>
</FrameLayout>

View File

@@ -5,10 +5,55 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".FragmentSdDataViewer"> tools:context=".FragmentSdDataViewer">
<!-- TODO: Update blank fragment layout --> <androidx.appcompat.widget.LinearLayoutCompat
<TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="253dp"
android:text="Fragment_OsdAlg" /> android:orientation="vertical">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/fragment_osdalg_tv1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Fragment_OsdAlg" />
<TextView
android:id="@+id/fragment_osdalg_tv2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="OSD Algorithm Status" />
<TextView
android:id="@+id/powerTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="---" />
<ProgressBar
android:id="@+id/powerProgressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="20dp" />
<TextView
android:id="@+id/spectrumTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="---" />
<ProgressBar
android:id="@+id/spectrumProgressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:minHeight="20dp" />
<com.github.mikephil.charting.charts.BarChart
android:id="@+id/chart1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.appcompat.widget.LinearLayoutCompat>
</FrameLayout> </FrameLayout>

View File

@@ -9,6 +9,9 @@
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" /> android:text="@string/hello_blank_fragment"
android:id="@+id/fragment_sddata_viewer_tv1"/>
</FrameLayout> </FrameLayout>