Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
140 views
in Technique[技术] by (71.8m points)

Android Studio: Help ... LiveData keeps separate values from different fragments

Please help me with a problem. I have the activity_main.xml set up with a score text box, a test button and a fragment container that swaps between 2 fragments.

The fragments are basically containers for buttons.

The "buttonTest" does exactly what "button1" from the fragment does (increments the score) but the test button (located on activity_main.xml) works and the fragment one ... does not

When viewing the logs ...i see that score does update when i click both buttons but with different values. If i click "buttonTest" it adds 5 to score so score = 5. On another click it adds another 5 so score = 10 If i click in the fragment on "button1" ... calling the same method score is now 1 then 2 then 3. If i now click "buttonTest" the score is 15.

The problem is that the LiveData keeps separate values depending on where the method was called. Allso the MainActivity observer does not update on the fragment call... only on the activity one.

Please help.

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private val viewModel: MainViewModel by viewModels()


override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
        val scoreSwitch = binding.scoreSwitch

         binding.buttonTest.setOnClickListener { viewModel.adaugaTren(5) }

 // score observer
 viewModel.scor.observe(this, Observer { newScore ->
     binding.txtPunctaj.text = newScore.toString()
     //todo sterge LOG
     Log.d("test","Scor Observer triggers")
 })

.......

class MainViewModel: ViewModel(){


    private val _score = MutableLiveData(0)
    val score: LiveData<Int>
    get() = _score


    fun adaugaTren(valoare:Int) {
            _scor.value = _scor.value?.plus(valoare)
            listaTrenuri.add(valoare)

        //testing
        Log.d("test","Trenuri: ${scor.value}")
            updateDisplay()
        }

    fun updateDisplay(){
      //  _trenuriDetinute.value = listaTrenuri.toString()

        _trenuriDetinute.value = TextUtils.join(", ",listaTrenuri)

        //testing
        Log.d("test","UpdateDisplay: ${scor.value}")
    }
...
}
class TrenuriFragment : Fragment() {

    private lateinit var binding: FragmentTrenuriBinding
    private val viewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_trenuri, container, false)

        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

      initButtons()
    }

    fun initButtons(){
        binding.button1.setOnClickListener { viewModel.adaugaTren(1)}
        ....
    }

}
question from:https://stackoverflow.com/questions/65870598/android-studio-help-livedata-keeps-separate-values-from-different-fragments

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In TrenuriFragment use activityViewModels

// viewModels is scoped in fragment but you need activity  
private val viewModel: MainViewModel by activityViewModels()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...