Android Studio Chronometer Rotation - 纵向工作,但不能横向工作...使用视图模型和 Kotlin
Posted
技术标签:
【中文标题】Android Studio Chronometer Rotation - 纵向工作,但不能横向工作...使用视图模型和 Kotlin【英文标题】:Android Studio Chronometer Rotation - Works in portrait but not in landscape... using view models & Kotlin 【发布时间】:2022-01-16 07:32:48 【问题描述】:时计正在纵向工作。问题是当它旋转到横向时,它不会从纵向的位置继续......但有趣的是当它回到纵向(纵向->横向->纵向)时,计时器会从它的位置拾取是最后一个。
请帮忙找出代码中的错误...谢谢!
这里是片段代码(NotesFragment.kt):
package com.genauapps.cis2818_proj4_runningapp
import android.os.Bundle
import android.os.SystemClock
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Chronometer
import androidx.lifecycle.ViewModelProvider
import com.genauapps.cis2818_proj4_runningapp.databinding.FragmentNotesBinding
import kotlin.math.absoluteValue
class NotesFragment : Fragment()
private lateinit var binding: FragmentNotesBinding
private lateinit var viewModel: NotesViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View?
binding = FragmentNotesBinding.inflate(layoutInflater)
viewModel = ViewModelProvider(this).get(NotesViewModel::class.java)
binding.notesFragmentBtStartStop.setOnClickListener onStartStop(viewModel.time.value!!)
if (viewModel.isWorking.value == true)
binding.notesFragmentChTime.base = viewModel.time.value!!
binding.notesFragmentChTime.start()
// Inflate the layout for this fragment
return binding.root
private fun onStartStop(startTime: Long)
if (!viewModel.isWorking.value!!)
if (startTime == 0L)
binding.notesFragmentChTime.base = SystemClock.elapsedRealtime()
else
binding.notesFragmentChTime.base = startTime
binding.notesFragmentChTime.start()
viewModel.isWorking.value = true
else
binding.notesFragmentChTime.stop()
viewModel.isWorking.value = false
viewModel.time.value = SystemClock.elapsedRealtime() - binding.notesFragmentChTime.base
Log.i("test", "Stopwatch time is $viewModel.time.value")
override fun onDestroy()
super.onDestroy()
viewModel.time.value = SystemClock.elapsedRealtime() - binding.notesFragmentChTime.base
// override fun onDestroyView()
// super.onDestroyView()
// viewModel.time.value = SystemClock.elapsedRealtime() - binding.notesFragmentChTime.base
//
这里是视图模型代码(NotesViewModel.kt):
package com.genauapps.cis2818_proj4_runningapp
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class NotesViewModel : ViewModel()
private val _time = MutableLiveData<Long>()
val time: MutableLiveData<Long> get() = _time
private val _date = MutableLiveData<String>()
val date: LiveData<String> get() = _date
private val _distance = MutableLiveData<Double>()
val distance: LiveData<Double> get() = _distance
private val _notes = MutableLiveData<String>()
val notes: LiveData<String> get() = _notes
private val _isWorking = MutableLiveData<Boolean>()
val isWorking: MutableLiveData<Boolean> get() = _isWorking
init
_time.value = 0L
_isWorking.value = false
fun timer(time: Long)
这里是 xml (fragment_notes.xml):
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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_
android:layout_
android:padding="10dp"
tools:context=".NotesFragment"
android:name="androidx.navigation.fragment.MainFragment"
>
<TextView
android:id="@+id/notes_fragment_tv_myworkout"
android:layout_
android:layout_
android:fontFamily="monospace"
android:text="@string/text_view_myworkout"
android:textSize="20sp"
android:textStyle="bold|italic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Chronometer
android:id="@+id/notes_fragment_ch_time"
android:layout_
android:layout_
android:layout_marginTop="8dp"
android:ems="10"
android:fontFamily="monospace"
android:hint="@string/edit_text_time"
android:textAlignment="center"
android:textColor="@color/black"
android:textColorHint="@color/black"
android:textSize="34sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/notes_fragment_tv_myworkout"
tools:ignore="TextContrastCheck" />
<EditText
android:id="@+id/notes_fragment_et_date"
android:layout_
android:layout_
android:layout_marginTop="8dp"
android:ems="10"
android:fontFamily="monospace"
android:hint="@string/edit_text_date"
android:importantForAutofill="no"
android:inputType="date"
android:minHeight="48dp"
android:textColorHint="@color/black"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/notes_fragment_ch_time" />
<EditText
android:id="@+id/notes_fragment_et_distance"
android:layout_
android:layout_
android:layout_marginTop="8dp"
android:ems="10"
android:fontFamily="monospace"
android:hint="@string/edit_text_distance"
android:inputType="numberDecimal"
android:textColorHint="@color/black"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/notes_fragment_et_date"
android:importantForAutofill="no" />
<EditText
android:id="@+id/notes_fragment_et_notes"
android:layout_
android:layout_
android:layout_marginTop="8dp"
android:ems="10"
android:fontFamily="monospace"
android:hint="@string/edit_text_notes"
android:importantForAutofill="no"
android:inputType="textCapSentences|textAutoCorrect"
android:minHeight="48dp"
android:textColor="@color/black"
android:textColorHint="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/notes_fragment_et_distance" />
<Button
android:id="@+id/notes_fragment_bt_start_stop"
android:layout_
android:layout_
android:layout_marginTop="32dp"
android:backgroundTint="@color/y_in_mn_blue"
android:fontFamily="monospace"
android:text="@string/button_text"
android:textAlignment="center"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/notes_fragment_et_notes" />
<Button
android:id="@+id/notes_fragment_bt_save"
android:layout_
android:layout_
android:layout_marginTop="8dp"
android:backgroundTint="@color/y_in_mn_blue"
android:fontFamily="monospace"
android:text="@string/button_text_save"
android:textAlignment="center"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/notes_fragment_bt_start_stop" />
</androidx.constraintlayout.widget.ConstraintLayout>
【问题讨论】:
【参考方案1】:首先,在你的“Activity tag”里面的AndroidManifest文件里面写:
android:configChanges="orientation|screenSize"
现在在 NotesFragment.kt 中:
package com.genauapps.cis2818_proj4_runningapp
import android.os.Bundle
import android.os.SystemClock
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import com.genauapps.cis2818_proj4_runningapp.databinding.FragmentNotesBinding
class NotesFragment : Fragment()
private lateinit var binding: FragmentNotesBinding
private lateinit var viewModel: NotesViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View?
binding = FragmentNotesBinding.inflate(layoutInflater)
viewModel = ViewModelProvider(this).get(NotesViewModel::class.java)
binding.notesFragmentBtStartStop.setOnClickListener
onStartStop(viewModel.time.value!!)
// Inflate the layout for this fragment
return binding.root
private fun onStartStop(startTime: Long)
if (viewModel.isWorking.value == false)
if (startTime == 0L)
binding.notesFragmentChTime.base = SystemClock.elapsedRealtime() -
startTime/ SystemClock.elapsedRealtime()
binding.notesFragmentChTime.start()
viewModel.isWorking.value = true
else
binding.notesFragmentChTime.base = SystemClock.elapsedRealtime() -
viewModel.time.value!!
binding.notesFragmentChTime.start()
viewModel.isWorking.value = true
else
binding.notesFragmentChTime.stop()
viewModel.isWorking.value = false
viewModel.time.value = SystemClock.elapsedRealtime() -
binding.notesFragmentChTime.base
// Saving Fragment State When Orientation Changes
private fun Fragment.onRestoreInstanceState(savedInstanceState: Bundle?)
onRestoreInstanceState(savedInstanceState)
onCreate(savedInstanceState)
请记住,每次更改方向时,实际上都是在调用“Destroy()”并重新创建视图,因此在纵向和横向方向之间切换之前必须“保存 Fragment 状态”。
【讨论】:
以上是关于Android Studio Chronometer Rotation - 纵向工作,但不能横向工作...使用视图模型和 Kotlin的主要内容,如果未能解决你的问题,请参考以下文章