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的主要内容,如果未能解决你的问题,请参考以下文章

android studio setting 在哪

如何解决android studio2.3导入android studio2.1的问题

Android studio上找不到setting?

android studio v4包冲突

如何用android studio 编成app

如何手动升级android studio?