From 69abc1d2593f59be545ddcac07fa6c96c01bd81c Mon Sep 17 00:00:00 2001 From: adoan5 <adolfandras@gmail.com> Date: Thu, 25 Apr 2024 15:55:31 +0200 Subject: [PATCH] Commit for moving --- app/build.gradle | 8 +- .../example/mindrover/EegSignalFragment.kt | 2 +- .../com/example/mindrover/TestFragment.kt | 26 +- .../com/example/mindrover/TrainFragment.kt | 36 +-- .../example/mindrover/TrainHomeFragment.kt | 6 +- .../mindrover/model/EEGDataListener.kt | 274 +++++------------- .../mindrover/model/ExperimentNavigator.kt | 18 +- .../example/mindrover/model/NeuralNetwork.kt | 116 ++++++++ app/src/main/res/layout/fragment_game.xml | 64 +++- app/src/main/res/layout/impedance_item.xml | 13 +- 10 files changed, 314 insertions(+), 249 deletions(-) create mode 100644 app/src/main/java/com/example/mindrover/model/NeuralNetwork.kt diff --git a/app/build.gradle b/app/build.gradle index 745bd06..ad9df2f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,9 +66,11 @@ dependencies { //Neural network // https://mavenlibs.com/maven/dependency/org.jetbrains.kotlinx/kotlin-deeplearning-api -// implementation ("org.jetbrains.kotlinx:kotlin-deeplearning-api:0.4.0") { -// exclude(group = "org.apache.commons", module = "commons-lang3") -// } +// implementation ("org.jetbrains.kotlinx:kotlin-deeplearning-api:0.4.0") + + implementation ("org.jetbrains.kotlinx:kotlin-deeplearning-api:0.4.0") { + exclude group:"org.apache.commons", module:"commons-lang3" + } // implementation 'org.tensorflow:tensorflow-lite:2.0.0' diff --git a/app/src/main/java/com/example/mindrover/EegSignalFragment.kt b/app/src/main/java/com/example/mindrover/EegSignalFragment.kt index 92bfa47..be562e3 100644 --- a/app/src/main/java/com/example/mindrover/EegSignalFragment.kt +++ b/app/src/main/java/com/example/mindrover/EegSignalFragment.kt @@ -16,12 +16,12 @@ import com.jjoe64.graphview.series.DataPoint import com.jjoe64.graphview.series.LineGraphSeries import kotlinx.coroutines.launch - /** * A simple [Fragment] subclass. * Use the [EegSignalFragment.newInstance] factory method to * create an instance of this fragment. */ + class EegSignalFragment : Fragment() { private val eegListener: EEGDataListener by viewModels() diff --git a/app/src/main/java/com/example/mindrover/TestFragment.kt b/app/src/main/java/com/example/mindrover/TestFragment.kt index d52ddfb..37c8d6c 100644 --- a/app/src/main/java/com/example/mindrover/TestFragment.kt +++ b/app/src/main/java/com/example/mindrover/TestFragment.kt @@ -60,19 +60,19 @@ class TestFragment : Fragment() { graphSeries = graphSeries.plus(LineGraphSeries()) } - lifecycleScope.launch { - - - lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { - eegListener.latestData.collect { -// if (graphView1 != null) -// Log.d("Retrevition", "Package size ${it.size}") - for (i in 0..it.size-1) { - graphSeries[i].resetData(it[i]) - } - } - } - } +// lifecycleScope.launch { +// +// +// lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { +// eegListener.latestData.collect { +//// if (graphView1 != null) +//// Log.d("Retrevition", "Package size ${it.size}") +// for (i in 0..it.size-1) { +// graphSeries[i].resetData(it[i]) +// } +// } +// } +// } } override fun onCreateView( diff --git a/app/src/main/java/com/example/mindrover/TrainFragment.kt b/app/src/main/java/com/example/mindrover/TrainFragment.kt index 376024c..ad6fb38 100644 --- a/app/src/main/java/com/example/mindrover/TrainFragment.kt +++ b/app/src/main/java/com/example/mindrover/TrainFragment.kt @@ -15,10 +15,11 @@ import com.example.mindrover.model.EEGDataListener import com.example.mindrover.model.ExperimentCommand import com.example.mindrover.model.ExperimentNavigator import com.example.mindrover.model.ExperimentState +import kotlin.math.exp class TrainFragment : Fragment() { -// private val experimentNavigator: ExperimentNavigator by viewModels() + private val experimentNavigator: ExperimentNavigator by viewModels() private val eegDataListener: EEGDataListener by viewModels() private lateinit var binding: FragmentTrainBinding @@ -27,8 +28,6 @@ class TrainFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - - } override fun onCreateView( @@ -39,6 +38,16 @@ class TrainFragment : Fragment() { // binding.imageView3.setImageResource(R.drawable.ic_arrow_circle_left) // binding.startTrainTexview.setText(R.string.left_command) + + return binding.root + } + + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + experimentRuns = true + val commandObserver = Observer<ExperimentCommand> { state -> binding.imageView3.setImageResource(state.imgId) if (experimentRuns) { @@ -46,8 +55,8 @@ class TrainFragment : Fragment() { binding.startTrainTexview.setText(state.textId) } } - eegDataListener.actualCommand.observe(viewLifecycleOwner, commandObserver) - +// eegDataListener.actualCommand.observe(viewLifecycleOwner, commandObserver) + experimentNavigator.actualCommand.observe(viewLifecycleOwner, commandObserver) val runningObserver = Observer<ExperimentState> { state -> if (state == ExperimentState.FINISHED) { @@ -55,33 +64,26 @@ class TrainFragment : Fragment() { } } - eegDataListener.doesExperimentRun.observe(viewLifecycleOwner, runningObserver) + experimentNavigator.doesExperimentRun.observe(viewLifecycleOwner, runningObserver) val intObserver = Observer<Int> { state -> binding.imageView3.setImageResource(state) } - eegDataListener.experimentRun.observe(viewLifecycleOwner, intObserver) - - + experimentNavigator.experimentRun.observe(viewLifecycleOwner, intObserver) - return binding.root - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - experimentRuns = true - val impedanceObserver = Observer<Array<Double>> { state -> Log.d("HEllo", "${state.size}") if (state.size > 0) binding.startTrainTexview.setText("${state[0]}") } -// eegDataListener.impedances.observe(viewLifecycleOwner, impedanceObserver) + eegDataListener.impedances.observe(viewLifecycleOwner, impedanceObserver) + + experimentNavigator.startExperiment(5) } diff --git a/app/src/main/java/com/example/mindrover/TrainHomeFragment.kt b/app/src/main/java/com/example/mindrover/TrainHomeFragment.kt index 47577d5..1be43a2 100644 --- a/app/src/main/java/com/example/mindrover/TrainHomeFragment.kt +++ b/app/src/main/java/com/example/mindrover/TrainHomeFragment.kt @@ -16,7 +16,7 @@ import com.example.mindrover.model.ExperimentNavigator class TrainHomeFragment : Fragment() { private lateinit var binding: FragmentTrainHomeBinding -// private val experimentNavigator: ExperimentNavigator by viewModels() + private val experimentNavigator: ExperimentNavigator by viewModels() private val eegDataListener: EEGDataListener by viewModels() @@ -40,8 +40,8 @@ class TrainHomeFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.button3.setOnClickListener { -// experimentNavigator.startExperiment(1) - eegDataListener.startExperiment(3) +// experimentNavigator.startExperiment(3) +// eegDataListener.startExperiment(3) findNavController().navigate(R.id.action_trainHomeFragment_to_trainFragment) } } diff --git a/app/src/main/java/com/example/mindrover/model/EEGDataListener.kt b/app/src/main/java/com/example/mindrover/model/EEGDataListener.kt index db91478..e9720e3 100644 --- a/app/src/main/java/com/example/mindrover/model/EEGDataListener.kt +++ b/app/src/main/java/com/example/mindrover/model/EEGDataListener.kt @@ -8,6 +8,7 @@ import androidx.lifecycle.viewModelScope import brainflow.BoardIds import brainflow.BoardShim import brainflow.BrainFlowInputParams +import brainflow.BrainFlowPresets import com.example.mindrover.R import com.jjoe64.graphview.series.DataPoint import kotlinx.coroutines.delay @@ -27,6 +28,9 @@ class EEGDataListener: ViewModel() { // private val _dataset = MutableLiveData<Array<DataPoint>>() // val dataset: LiveData<Array<DataPoint>> = _dataset + private val _lastData = MutableLiveData<Array<Array<DataPoint>>>() + val lastData: LiveData<Array<Array<DataPoint>>> = _lastData + private val _impedances = MutableLiveData<Array<Double>>() val impedances: LiveData<Array<Double>> = _impedances @@ -49,108 +53,75 @@ class EEGDataListener: ViewModel() { val latestData: Flow<Array<Array<DataPoint>>> = flow { - var currentData = arrayOf<Array<DataPoint>>() - for (i in 0 until numOfChannels) { - wholeData = wholeData.plus(arrayOf<DataPoint>()) - currentData = currentData.plus(arrayOf<DataPoint>()) - } - - _impedances.value = emptyArray() - repeat(numOfChannels) { - _impedances.value = _impedances.value?.plus(Random.nextDouble()*20+2) - } +// fun startStreaming() { +// viewModelScope.launch { -//------------------------------------------------------------------------------------------------------------ -// val commands= mutableListOf<ExperimentCommand>() -// -// val left = ExperimentCommand("left", R.drawable.ic_arrow_circle_left, R.string.left_command) -// val right = ExperimentCommand("right", R.drawable.ic_arrow_circle_right, R.string.right_command) -// val action = ExperimentCommand("action", R.drawable.ic_cancel, R.string.no_command) -// -// repeat(5) { -// commands.add(left) -// commands.add(right) -// } -// -// commands.shuffle() -// -// var commandnumtest = 1 -// var testtimer = 1 -//------------------------------------------------------------------------------------------------------------ + var currentData = arrayOf<Array<DataPoint>>() + for (i in 0 until numOfChannels) { + wholeData = wholeData.plus(arrayOf<DataPoint>()) + currentData = currentData.plus(arrayOf<DataPoint>()) + } + _impedances.value = emptyArray() + repeat(numOfChannels) { + _impedances.value = _impedances.value?.plus(Random.nextDouble()*20+2) + } - while (true) { -//Get last package of data - for (i in 0..5) { - time++ + while (true) { - for (ch in 0 until numOfChannels) { - if ((time.toInt() % 4000) == 20) { - wholeData[ch] = wholeData[ch].plus(DataPoint(time, 20.0)) - } - else { - wholeData[ch] = - wholeData[ch].plus(DataPoint(time, Random.nextDouble() * 10)) + //Get last package of data + for (i in 0..5) { + time++ + + for (ch in 0 until numOfChannels) { + if ((time.toInt() % 4000) == 20) { + wholeData[ch] = wholeData[ch].plus(DataPoint(time, 20.0)) + } + else { + wholeData[ch] = + wholeData[ch].plus(DataPoint(time, Random.nextDouble() * 10)) + } } } - } - -//Update dataset - var imps = _impedances.value!! - for (i in 0 until numOfChannels) { - imps[i] = imps[i] + (Random.nextDouble() - 0.5) - } - _impedances.value = imps - - delay(100) - -//Update impedances - val size = minOf(100, wholeData[0].size) - for (ch in 0 until numOfChannels) { - val data = wholeData[ch].takeLast(size).toTypedArray() - for (i in 0 until size) { - data[i] = DataPoint(i.toDouble(), data[i].y) + //Update dataset + var imps = _impedances.value!! + for (i in 0 until numOfChannels) { + imps[i] = imps[i] + (Random.nextDouble() - 0.5) } - currentData[ch] = data - } + _impedances.value = imps + + delay(100) -//Free memory with whole data + //Update impedances + val size = minOf(100, wholeData[0].size) - if (wholeData[0].size > MAXSTOREDPOINT*2) { for (ch in 0 until numOfChannels) { - wholeData[ch] = wholeData[ch].takeLast(MAXSTOREDPOINT).toTypedArray() + val data = wholeData[ch].takeLast(size).toTypedArray() + for (i in 0 until size) { + data[i] = DataPoint(i.toDouble(), data[i].y) + } + currentData[ch] = data } - } - - -// testtimer+=1 -// if (testtimer%35==0) { -// if (testtimer%14 == 0) { -// commandnumtest += 1 -// commandnumtest = commandnumtest % 10 -// _actualCommand.value = commands[commandnumtest % 10] -// } else { -// _actualCommand.value = action -// } -// -//// if (commandnumtest % 2 == 1) -//// _actualCommand.value = right -//// else -//// _actualCommand.value = left -// Log.d("Feri", "${_actualCommand.value}") -// } + //Free memory with whole data + if (wholeData[0].size > MAXSTOREDPOINT*2) { + for (ch in 0 until numOfChannels) { + wholeData[ch] = wholeData[ch].takeLast(MAXSTOREDPOINT).toTypedArray() + } + } - emit(currentData) + _lastData.value = currentData + emit(currentData) - } + } +// } } @@ -159,7 +130,7 @@ class EEGDataListener: ViewModel() { // } init { - testCoroutine() +// testCoroutine() _connection.value = ConnectionState.NO_CONNECTION // establishConnection() } @@ -170,11 +141,30 @@ class EEGDataListener: ViewModel() { try { val par = BrainFlowInputParams() + par.set_ip_protocol(22) par.ip_address + val shim = BoardShim(38, par) +// val shim = BoardShim(BoardIds.PIEEG_BOARD, BrainFlowInputParams()) - BoardShim.enable_board_logger() - BoardShim.get_eeg_channels(4) - Log.d("Connection", "Ip address: ${par.ip_protocol}") +// try { +// BoardShim.enable_board_logger() + +// } catch (e: Exception) { +// Log.d("EEGException","Connection enabled fail") +// } +// BoardShim.get_eeg_channels(10) +// BoardShim.enable_board_logger() + + Log.d("HEllo", "BoardId:${BoardIds.PIEEG_BOARD}") +// try { +// val shim = BoardShim(BoardIds.PIEEG_BOARD, BrainFlowInputParams()) +// println(shim.get_board_data().size) +// } catch (e: Exception) { +// +// } + + + Log.d("EEGConnection", "Ip address: ${par.ip_protocol}") // Log.d("Connection", "Create dsocket") // val port = 4210 @@ -183,12 +173,16 @@ class EEGDataListener: ViewModel() { // Log.d("Connection", "------------------Created dsocket--------------------") // var serverAddress = InetAddress.getByName("192.168.4.1") + + + _connection.value = ConnectionState.PENDING delay(2000) test_connection_num++ - if (test_connection_num%2 == 0) { + if (test_connection_num%2 == 1) { _connection.value = ConnectionState.CONNECTION +// startStreaming() } else { _connection.value = ConnectionState.NO_CONNECTION } @@ -198,114 +192,6 @@ class EEGDataListener: ViewModel() { } } } - - - fun testCoroutine() { - - viewModelScope.launch { - while (true) { - delay(90) - - latestData.collect() { -// Log.d("Jeromos", "collected ${it.size}") - } - -// Log.d("Signal", "Signal: $signal1") - } - } - } - - - -// suspend fun streamSimulation() { -// for (i in 1..10) { -// delay(20) -// addRandomData() -// } -// -// while(true) { -// for (i in 1..10) { -// delay(20) -// addRandomData() -// } -// updateDataset(20) -// } -// } - -// fun addRandomData() { -// time++ -// wholeData.plus(DataPoint(time, Random.nextDouble()*10)) -// } -// -// fun updateDataset(num: Int) { -// _dataset.value = wholeData.takeLast(num).toTypedArray() -// } - - - - //------------------------------------------------------------------------------------------------------------------------- - - private val _actualCommand = MutableLiveData<ExperimentCommand>() - val actualCommand: LiveData<ExperimentCommand> = _actualCommand - - private val _doesExperimentRun = MutableLiveData<ExperimentState>() - val doesExperimentRun: LiveData<ExperimentState> = _doesExperimentRun - - private val _experimentRun = MutableLiveData<Int>() - val experimentRun: LiveData<Int> = _experimentRun - - - - - init { - _doesExperimentRun.value = ExperimentState.PENDING - _experimentRun.value = R.drawable.ic_arrow_circle_right - } - - fun startExperiment(num: Int) { - - viewModelScope.launch { - - - val left = ExperimentCommand("left", R.drawable.ic_arrow_circle_left, R.string.left_command) - val right = ExperimentCommand("right", R.drawable.ic_arrow_circle_right, R.string.right_command) - val action = ExperimentCommand("action", R.drawable.ic_cancel, R.string.no_command) - - val commands= mutableListOf<ExperimentCommand>() - - repeat(num) { - commands.add(left) - commands.add(right) - } - - commands.shuffle() - - _doesExperimentRun.value = ExperimentState.STARTED - for (comm in commands) { - Log.d("Experiment", comm.id) - _actualCommand.value = comm - _experimentRun.value = comm.imgId - Log.d("Experiment__", "${_experimentRun.value}") - Log.d("Experiment__", "${experimentRun.value}") - - delay(1000) -// actualCommand.value?.let { Log.d("Experiment", it.id) } - _actualCommand.value = action - _experimentRun.value = R.drawable.ic_cancel - delay(1000) - //TODO: Save data - } - _doesExperimentRun.value = ExperimentState.FINISHED - - Log.d("Jeromos", "${_doesExperimentRun.value}") - } - } -} - -data class ExperimentCommand(val id: String, val imgId:Int, val textId:Int) - -enum class ExperimentState { - PENDING, STARTED, FINISHED } diff --git a/app/src/main/java/com/example/mindrover/model/ExperimentNavigator.kt b/app/src/main/java/com/example/mindrover/model/ExperimentNavigator.kt index 81c3ca8..67f761c 100644 --- a/app/src/main/java/com/example/mindrover/model/ExperimentNavigator.kt +++ b/app/src/main/java/com/example/mindrover/model/ExperimentNavigator.kt @@ -10,11 +10,11 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch -//data class ExperimentCommand(val id: String, val imgId:Int, val textId:Int) -// -//enum class ExperimentState { -// PENDING, STARTED, FINISHED -//} +data class ExperimentCommand(val id: String, val imgId:Int, val textId:Int) + +enum class ExperimentState { + PENDING, STARTED, FINISHED +} @@ -39,8 +39,8 @@ class ExperimentNavigator: ViewModel() { val left = ExperimentCommand("left", R.drawable.ic_arrow_circle_left, R.string.left_command) - val right = ExperimentCommand("right", R.drawable.ic_arrow_circle_left, R.string.right_command) - val action = ExperimentCommand("action", R.drawable.ic_arrow_circle_left, R.string.no_command) + val right = ExperimentCommand("right", R.drawable.ic_arrow_circle_right, R.string.right_command) + val action = ExperimentCommand("action", R.drawable.ic_cancel, R.string.no_command) val commands= mutableListOf<ExperimentCommand>() @@ -58,10 +58,10 @@ class ExperimentNavigator: ViewModel() { _actualCommand.value = comm _experimentRun.value = comm.imgId Log.d("Experiment__", "${_experimentRun.value}") - delay(1000) + delay(2000) // actualCommand.value?.let { Log.d("Experiment", it.id) } _actualCommand.value = action - delay(1000) + delay(2000) //TODO: Save data } _doesExperimentRun.value = ExperimentState.FINISHED diff --git a/app/src/main/java/com/example/mindrover/model/NeuralNetwork.kt b/app/src/main/java/com/example/mindrover/model/NeuralNetwork.kt new file mode 100644 index 0000000..2a5aadf --- /dev/null +++ b/app/src/main/java/com/example/mindrover/model/NeuralNetwork.kt @@ -0,0 +1,116 @@ +package com.example.mindrover.model + +import org.jetbrains.kotlinx.dl.api.core.Sequential +import org.jetbrains.kotlinx.dl.api.core.activation.Activations +import org.jetbrains.kotlinx.dl.api.core.initializer.Constant +import org.jetbrains.kotlinx.dl.api.core.initializer.GlorotNormal +import org.jetbrains.kotlinx.dl.api.core.initializer.Zeros +import org.jetbrains.kotlinx.dl.api.core.layer.convolutional.Conv2D +import org.jetbrains.kotlinx.dl.api.core.layer.convolutional.ConvPadding +import org.jetbrains.kotlinx.dl.api.core.layer.core.Dense +import org.jetbrains.kotlinx.dl.api.core.layer.core.Input +import org.jetbrains.kotlinx.dl.api.core.layer.pooling.AvgPool2D +import org.jetbrains.kotlinx.dl.api.core.layer.reshaping.Flatten +import org.jetbrains.kotlinx.dl.dataset.OnHeapDataset +import org.jetbrains.kotlinx.dl.dataset.handler.NUMBER_OF_CLASSES +import org.jetbrains.kotlinx.dl.dataset.mnist + + +private const val EPOCHS = 3 +private const val TRAINING_BATCH_SIZE = 1000 +private const val NUM_CHANNELS = 1L +private const val IMAGE_SIZE = 28L +private const val SEED = 12L +private const val TEST_BATCH_SIZE = 1000 + + +class NeuralNetwork { + + + private lateinit var model: Sequential + + val network = Sequential.of( + Input( + 6L, + 200L, + 100 + ) + ) + + init { + + val (train, test) = mnist() + + val heapdata: OnHeapDataset + + model = Sequential.of( + + Input( + IMAGE_SIZE, + IMAGE_SIZE, + NUM_CHANNELS + ), + Conv2D( + filters = 6, + kernelSize = intArrayOf(5, 5), + strides = intArrayOf(1, 1, 1, 1), + activation = Activations.Tanh, + kernelInitializer = GlorotNormal(SEED), + biasInitializer = Zeros(), + padding = ConvPadding.SAME + ), + AvgPool2D( + poolSize = intArrayOf(1, 2, 2, 1), + strides = intArrayOf(1, 2, 2, 1), + padding = ConvPadding.VALID + ), + Conv2D( + filters = 16, + kernelSize = intArrayOf(5, 5), + strides = intArrayOf(1, 1, 1, 1), + activation = Activations.Tanh, + kernelInitializer = GlorotNormal(SEED), + biasInitializer = Zeros(), + padding = ConvPadding.SAME + ), + AvgPool2D( + poolSize = intArrayOf(1, 2, 2, 1), + strides = intArrayOf(1, 2, 2, 1), + padding = ConvPadding.VALID + ), + Flatten(), // 3136 + Dense( + outputSize = 120, + activation = Activations.Tanh, + kernelInitializer = GlorotNormal(SEED), + biasInitializer = Constant(0.1f) + ), + Dense( + outputSize = 84, + activation = Activations.Tanh, + kernelInitializer = GlorotNormal(SEED), + biasInitializer = Constant(0.1f) + ), + Dense( + outputSize = NUMBER_OF_CLASSES, + activation = Activations.Linear, + kernelInitializer = GlorotNormal(SEED), + biasInitializer = Constant(0.1f) + ) + + ) + + } + + fun saveNeuralNetwork(name: String) { +// model.save('keras-cifar-10/weights', savingFormat='h5') +// +// +// model_json = model.to_json() +// with open("keras-cifar-10/model.json", "w") as json_file: +// json_file.write(model_json) + + } + + +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_game.xml b/app/src/main/res/layout/fragment_game.xml index adb8e39..f1ce432 100644 --- a/app/src/main/res/layout/fragment_game.xml +++ b/app/src/main/res/layout/fragment_game.xml @@ -5,10 +5,68 @@ android:layout_height="match_parent" tools:context=".GameFragment"> - <!-- TODO: Update blank fragment layout --> - <TextView + <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" - android:text="@string/hello_blank_fragment" /> + android:orientation="vertical"> + + <Space + android:layout_width="match_parent" + android:layout_height="100px" /> + + <TextView + android:id="@+id/textView2" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="TextView" /> + + <Space + android:layout_width="match_parent" + android:layout_height="100px" /> + + <RadioGroup + android:layout_width="match_parent" + android:layout_height="278dp"> + + <RadioButton + android:id="@+id/radioButton3" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="RadioButton" /> + + <RadioButton + android:id="@+id/radioButton4" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="RadioButton" /> + + <RadioButton + android:id="@+id/radioButton5" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="RadioButton" /> + + <RadioButton + android:id="@+id/radioButton6" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="RadioButton" /> + + </RadioGroup> + + <Space + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <Button + android:id="@+id/button6" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="Button" /> + + <Space + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + </LinearLayout> </FrameLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/impedance_item.xml b/app/src/main/res/layout/impedance_item.xml index b5b6eae..5f20669 100644 --- a/app/src/main/res/layout/impedance_item.xml +++ b/app/src/main/res/layout/impedance_item.xml @@ -1,18 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout -xmlns:android="http://schemas.android.com/apk/res/android" -xmlns:app="http://schemas.android.com/apk/res-auto" +<LinearLayout 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" android:layout_width="match_parent" -android:layout_height="wrap_content" -android:orientation="horizontal"> + android:layout_height="wrap_content" + android:gravity="center" + android:orientation="horizontal"> <TextView android:id="@+id/impedanceChannelTextview" - android:layout_width="wrap_content" + android:layout_width="70dp" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="24sp" + android:layout_margin="20dp" tools:text="Channel" /> <TextView -- GitLab