I am trying to build a multi page form for an application. As per suggestions here I am attempting to use a ViewModel to store the data input by the user to easily get it in another fragment, and to update the edittext to their previous input if they navigate back and forth. As well the application must have view binding.
However, when attempting to retrieve the input in a toast message in the last fragment or put it in the edittext, I get this as an output "androidx.lifecycle.MutableLiveData@8177d2c"
Why is this happening? I am using .toString() methods with getText() so I don't know why
My code:
SharedViewModel.java
package com.loopbreakr.viewmodelform;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.MutableLiveData;
public class SharedViewModel extends ViewModel {
private MutableLiveData<CharSequence> answerOneText = new MutableLiveData<>();
private MutableLiveData<CharSequence> answerTwoText = new MutableLiveData<>();
private MutableLiveData<CharSequence> answerThreeText = new MutableLiveData<>();
public void setAnswerOneText(CharSequence input) {
answerOneText.setValue(input);
}
public void setAnswerTwoText(CharSequence input) {
answerTwoText.setValue(input);
}
public void setAnswerThreeText(CharSequence input){
answerThreeText.setValue(input);
}
public MutableLiveData<CharSequence> getAnswerOneText() {
return answerOneText;
}
public MutableLiveData<CharSequence> getAnswerTwoText() {
return answerTwoText;
}
public MutableLiveData<CharSequence> getAnswerThreeText() {
return answerThreeText;
}
}
MainActivity.java
package com.loopbreakr.viewmodelform;
import androidx.appcompat.app.AppCompatActivity;
import androidx.navigation.NavController;
import androidx.navigation.fragment.NavHostFragment;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
NavController navController = navHostFragment.getNavController();
}
}
PageOne.java fragment that I am trying to retrieve data from
package com.loopbreakr.viewmodelform;
import android.app.Activity;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import com.loopbreakr.viewmodelform.databinding.FragmentPageOneBinding;
public class PageOne extends Fragment {
private SharedViewModel sharedViewModel;
private FragmentPageOneBinding binding = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewDataBinding fragmentBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_page_one,container,false);
binding = (FragmentPageOneBinding) fragmentBinding;
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
if(binding != null){
binding.pageOneInput.setText(sharedViewModel.getAnswerOneText().toString());
binding.nextToTwo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sharedViewModel.setAnswerOneText(binding.pageOneInput.getText().toString());
goNext();
}
});
binding.returnButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
goBack();
}
});
}
}
public void goNext() {
NavController navController = Navigation.findNavController(getView());
navController.navigate(R.id.action_pageOne_to_pageTwo);
}
public void goBack(){
NavController navController = Navigation.findNavController(getView());
navController.navigate((R.id.action_pageOne_to_description));
}
}
Last fragment PageThree.java where I attempt to get the data and display it as a toast message
package com.loopbreakr.viewmodelform;
import android.app.Activity;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import com.loopbreakr.viewmodelform.databinding.FragmentPageOneBinding;
public class PageOne extends Fragment {
private SharedViewModel sharedViewModel;
private FragmentPageOneBinding binding = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewDataBinding fragmentBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_page_one,container,false);
binding = (FragmentPageOneBinding) fragmentBinding;
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
if(binding != null){
binding.pageOneInput.setText(sharedViewModel.getAnswerOneText().toString());
binding.nextToTwo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sharedViewModel.setAnswerOneText(binding.pageOneInput.getText().toString());
goNext();
}
});
binding.returnButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
goBack();
}
});
}
}
public void goNext() {
NavController navController = Navigation.findNavController(getView());
navController.navigate(R.id.action_pageOne_to_pageTwo);
}
public void goBack(){
NavController navController = Navigation.findNavController(getView());
navController.navigate((R.id.action_pageOne_to_description));
}
}
Also, here are the XMLs incase they are relevant
activity_main.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_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_page_one.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="viewModel"
type="com.loopbreakr.viewmodelform.SharedViewModel"/>
</data>
<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_width="match_parent"
android:layout_height="match_parent"
tools:context=".PageOne">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
<Button
android:id="@+id/nextToTwo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="@+id/returnButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Return"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<MultiAutoCompleteTextView
android:id="@+id/pageOneInput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textAutoCorrect|textMultiLine"
android:maxLines="4"
android:minLines="4"
app:layout_constraintBottom_toBottomOf="@+id/textView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>