Skip to content

Commit

Permalink
[Android] virtual-device-app: Implement door lock view (#30778)
Browse files Browse the repository at this point in the history
* virtual-device-app: Implement common layout

Signed-off-by: Jaehoon You <[email protected]>
Signed-off-by: Charles Kim <[email protected]>

* virtual-device-app: Implement doorlock view

Signed-off-by: Jaehoon You <[email protected]>
Signed-off-by: Charles Kim <[email protected]>

---------

Signed-off-by: Jaehoon You <[email protected]>
Signed-off-by: Charles Kim <[email protected]>
  • Loading branch information
Jaehoon-You authored and pull[bot] committed Dec 15, 2023
1 parent e6ac08d commit 1212952
Show file tree
Hide file tree
Showing 12 changed files with 233 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="matter_on_off_switch" translatable="false">Matter OnOff Switch</string>
<string name="matter_door_lock" translatable="false">Matter Door Lock</string>
<string name="matter_device" translatable="false">Matter Device</string>
<string name="description_icon" translatable="false">icon</string>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.matter.virtual.device.app.core.model.databinding

import androidx.lifecycle.LiveData

data class SeekbarData(val progress: LiveData<Int>, val min: Int = 0, val max: Int = 100)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
<path android:fillColor="@android:color/white" android:pathData="M12,12m-5,0a5,5 0,1 1,10 0a5,5 0,1 1,-10 0"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M19.5,12c0,-0.23 -0.01,-0.45 -0.03,-0.68l1.86,-1.41c0.4,-0.3 0.51,-0.86 0.26,-1.3l-1.87,-3.23c-0.25,-0.44 -0.79,-0.62 -1.25,-0.42l-2.15,0.91c-0.37,-0.26 -0.76,-0.49 -1.17,-0.68l-0.29,-2.31C14.8,2.38 14.37,2 13.87,2h-3.73C9.63,2 9.2,2.38 9.14,2.88L8.85,5.19c-0.41,0.19 -0.8,0.42 -1.17,0.68L5.53,4.96c-0.46,-0.2 -1,-0.02 -1.25,0.42L2.41,8.62c-0.25,0.44 -0.14,0.99 0.26,1.3l1.86,1.41C4.51,11.55 4.5,11.77 4.5,12s0.01,0.45 0.03,0.68l-1.86,1.41c-0.4,0.3 -0.51,0.86 -0.26,1.3l1.87,3.23c0.25,0.44 0.79,0.62 1.25,0.42l2.15,-0.91c0.37,0.26 0.76,0.49 1.17,0.68l0.29,2.31C9.2,21.62 9.63,22 10.13,22h3.73c0.5,0 0.93,-0.38 0.99,-0.88l0.29,-2.31c0.41,-0.19 0.8,-0.42 1.17,-0.68l2.15,0.91c0.46,0.2 1,0.02 1.25,-0.42l1.87,-3.23c0.25,-0.44 0.14,-0.99 -0.26,-1.3l-1.86,-1.41C19.49,12.45 19.5,12.23 19.5,12zM12.04,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5s3.5,1.57 3.5,3.5S13.97,15.5 12.04,15.5z"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

<variable
name="seekbarData"
type="com.matter.virtual.device.app.core.model.databinding.SeekbarData" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/device_item_margin_horizontal"
android:layout_marginTop="@dimen/device_item_margin_top"
android:background="@drawable/menu_item_bg"
android:gravity="center_vertical"
android:paddingStart="@dimen/device_item_padding_start"
android:paddingTop="@dimen/device_item_padding_top"
android:paddingEnd="@dimen/device_item_padding_end"
android:paddingBottom="@dimen/device_item_padding_bottom">

<TextView
android:id="@+id/title_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
android:textSize="@dimen/device_item_text_size"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/value_text"
android:layout_width="@dimen/device_item_value_text_width"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
android:textSize="@dimen/device_item_value_text_size"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_text" />

<SeekBar
android:id="@+id/seekbar"
android:layout_width="@dimen/device_item_seekbar_width"
android:layout_height="@dimen/device_item_seekbar_height"
android:contentDescription="@string/description_seekbar"
android:max="@{seekbarData.max}"
android:min="@{seekbarData.min}"
android:progress="@{seekbarData.progress}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/value_text"
app:layout_constraintTop_toBottomOf="@+id/title_text" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/device_item_margin_horizontal"
android:layout_marginTop="@dimen/device_item_margin_top"
android:background="@drawable/menu_item_bg"
android:gravity="center_vertical"
android:paddingStart="@dimen/device_item_padding_start"
android:paddingTop="@dimen/device_item_padding_top"
android:paddingEnd="@dimen/device_item_padding_end"
android:paddingBottom="@dimen/device_item_padding_bottom">

<TextView
android:id="@+id/title_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
android:textSize="@dimen/device_item_text_size"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/value_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
android:textSize="@dimen/device_item_value_text_size"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_text" />

<ImageView
android:id="@+id/button"
android:layout_width="@dimen/device_item_button_width"
android:layout_height="@dimen/device_item_button_height"
android:contentDescription="@string/description_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="description_button" translatable="false">button</string>
<string name="description_seekbar" translatable="false">seekbar</string>

<string name="more_menu_reset" translatable="false">Reset</string>

<string name="dialog_factory_reset_message">"The Matter device app will be reset and closed. Continue?"</string>
<string name="dialog_user_factory_reset_message">"The commissioning was not completed. The Matter device app will be reset and closed. Continue?"</string>
<string name="dialog_fabric_removed_factory_reset_message">"The fabric was removed. The Matter device app will be reset and closed."</string>
<string name="dialog_fabric_removed_factory_reset_message">"The fabric was removed. The Matter device app will be reset and closed."</string>

<string name="battery">Battery</string>
<string name="battery_format" translatable="false">%d &lt;small>&lt;small>%%&lt;/small>&lt;/small></string>

<string name="cancel">Cancel</string>
<string name="on_off_switch_power_on">On</string>
<string name="on_off_switch_power_off">Off</string>
</resources>
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.matter.virtual.device.app.feature.closure

import android.text.Html
import android.widget.SeekBar
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.navArgs
import com.matter.virtual.device.app.core.model.databinding.SeekbarData
import com.matter.virtual.device.app.core.model.matter.LockState
import com.matter.virtual.device.app.core.ui.BaseFragment
import com.matter.virtual.device.app.core.ui.databinding.LayoutAppbarBinding
import com.matter.virtual.device.app.feature.closure.databinding.FragmentDoorLockBinding
Expand All @@ -16,6 +21,7 @@ class DoorLockFragment :
BaseFragment<FragmentDoorLockBinding, DoorLockViewModel>(R.layout.fragment_door_lock) {

override val viewModel: DoorLockViewModel by viewModels()
private var lockState: LockState = LockState.LOCKED

@OptIn(ExperimentalSerializationApi::class)
override fun setupNavArgs() {
Expand All @@ -25,9 +31,55 @@ class DoorLockFragment :

override fun setupAppbar(): LayoutAppbarBinding = binding.appbar

override fun setupUi() {}
override fun setupUi() {
/** title text */
binding.appbar.toolbarTitle.text = getString(R.string.matter_door_lock)

override fun setupObservers() {}
/** LockState layout */
binding.doorLockLockStateLayout.titleText.text = getString(R.string.door_lock_lock_state)
binding.doorLockLockStateLayout.button.setImageResource(R.drawable.round_settings_24)
binding.doorLockLockStateLayout.button.setOnClickListener { showLockStatePopup() }

/** Send alarm layout */
binding.doorLockSendAlarmLayout.valueText.text =
getString(R.string.door_lock_send_lock_alarm_event)
binding.doorLockSendAlarmLayout.button.setImageResource(
R.drawable.round_radio_button_checked_24
)
binding.doorLockSendAlarmLayout.button.setOnClickListener {
viewModel.onClickSendLockAlarmEventButton()
}

/** Battery layout */
binding.doorLockBatteryLayout.titleText.text = getString(R.string.battery)
binding.doorLockBatteryLayout.seekbarData =
SeekbarData(progress = viewModel.batteryRemainingPercentage)
binding.doorLockBatteryLayout.seekbar.setOnSeekBarChangeListener(
object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
viewModel.updateBatterySeekbarProgress(progress)
}

override fun onStartTrackingTouch(seekBar: SeekBar) {}

override fun onStopTrackingTouch(seekBar: SeekBar) {
viewModel.updateBatteryStatusToCluster(seekBar.progress)
}
}
)
}

override fun setupObservers() {
viewModel.lockState.observe(viewLifecycleOwner) {
this.lockState = it
binding.doorLockLockStateLayout.valueText.text = it.toString()
}

viewModel.batteryRemainingPercentage.observe(viewLifecycleOwner) {
val text: String = getString(R.string.battery_format, it)
binding.doorLockBatteryLayout.valueText.text = Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY)
}
}

override fun onResume() {
Timber.d("onResume()")
Expand All @@ -38,4 +90,23 @@ class DoorLockFragment :
Timber.d("onDestroy()")
super.onDestroy()
}

private fun showLockStatePopup() {
val list =
arrayOf(
LockState.NOT_FULLY_LOCKED.toString(),
LockState.LOCKED.toString(),
LockState.UNLOCKED.toString(),
LockState.UNLATCHED.toString()
)

AlertDialog.Builder(requireContext())
.setTitle(R.string.door_lock_lock_state)
.setSingleChoiceItems(list, list.indexOf(this.lockState.toString())) { dialog, which ->
viewModel.setLockState(enumValueOf(list[which]))
dialog.dismiss()
}
.setNegativeButton(R.string.cancel, null)
.show()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,9 @@ constructor(
super.onCleared()
}

fun onClickButton() {
Timber.d("onClickButton()")
viewModelScope.launch {
Timber.d("current lockState value = ${_lockState.value}")
if (_lockState.value == LockState.LOCKED) {
Timber.d("set value = unlocked")
setLockStateUseCase(LockState.UNLOCKED)
} else {
Timber.d("set value = locked")
setLockStateUseCase(LockState.LOCKED)
}
}
fun setLockState(lockState: LockState) {
Timber.d("setLockState():new:$lockState")
viewModelScope.launch { setLockStateUseCase(lockState) }
}

fun onClickSendLockAlarmEventButton() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
Expand All @@ -15,6 +16,34 @@
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<LinearLayout
android:id="@+id/door_lock_function_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<include
android:id="@+id/door_lock_lock_state_layout"
layout="@layout/layout_item_title_value_simple_button" />

<include
android:id="@+id/door_lock_send_alarm_layout"
layout="@layout/layout_item_title_value_simple_button" />

<include
android:id="@+id/door_lock_battery_layout"
layout="@layout/layout_item_title_value_seekbar" />
</LinearLayout>

<!-- Bottom Space -->
<include layout="@layout/layout_space_bottom" />
<!-- Bottom Space -->
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
</layout>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="door_lock_lock_state">Lock state</string>
<string name="door_lock_send_lock_alarm_event">Send Alarm</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
<string name="setup_network_notification_message">Make sure your Mobile/Hub/Device App are connected to the same Wi-Fi network.</string>
<string name="save">Save</string>
<string name="toast_discriminator" translatable="false">Invalid input value</string>
<string name="cancel">Cancel</string>
<string name="start">Start</string>
<string name="setup_ssid_text" translatable="false">Wi-Fi : %1$s</string>
<string name="setup_discriminator_text" translatable="false">%1$s : %2$s</string>
Expand Down

0 comments on commit 1212952

Please sign in to comment.