Issue
I wondered if it's possible to pass a String data which has declared in Activity class and pass the String data to ViewModel class then pass the data to Fragment class.
ViewModel Class
class TimeTableViewModel extends ViewModel {
private MutableLiveData<String> start_time_str = new MutableLiveData<>();
void send_StartTime(String start_Time){
start_time_str.setValue(start_Time);
}
LiveData<String> get_StartTime(){
return start_time_str;
}}
In ViewModel Class, I have MutableLiveData<String> start_time_str
and it has been initialized as new MutableLiveData<>();
I would like to use void send_StartTime(String start_Time)
function in Activity class to set value of argument String start_Time
and call the start_time_str
in Fragment class.
Activity Class
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()){
case android.R.id.home:
finish();
break;
case R.id.add_schedule_save:
String start_time_str = startTime.getText().toString();
Intent intent_restart0 = new Intent(TimeTable_Add_New_Schedule.this, MainActivity.class);
startActivity(intent_restart0);
TimeTableViewModel timeTableViewModel = new TimeTableViewModel();
timeTableViewModel.send_StartTime(start_time_str);
Toast.makeText(this,""+start_time_str,Toast.LENGTH_LONG).show();
break;
}
return super.onOptionsItemSelected(item);
}
Fragment Class
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
TimeTableViewModel timeTableViewModel = new TimeTableViewModel();
timeTableViewModel.get_StartTime().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String s) {
mon_textView_11.setText(s);
}
});
}
In the Fragment class I call get_StartTime()
function to get start_time_str
and set the String value to my TextView. I think the start_time_str
has been successfully set by function of timeTableViewModel.send_StartTime(start_time_str);
in the Activity Class because of Toast.maketext is worked like a charm. However the TextView is not shown anything. I have tested Text Color is not white so that if the string value is correctly called, it should be appear on screen. If you have any suggestions, I would love to hear your advice.
Thank you very much.
Solution
It really depends on how do you create your ViewModel
instance. Now you are creating ViewModel
by its constructor, but that is not a proper way. You should use ViewModelProvider
or extension methods that were created by Google team.
If you go with ViewModelProvider
you should do it like this:
TimeTableViewModel viewModel = new ViewModelProvider(this).get(TimeTableViewModel.class);
It is important to pass the correct context to ViewModelProvider
constructor call. If you are in fragment and you will just use getContext()
instead of getActivity()
, you will not get the same instance as it was created in Activity. You will create a new instance of ViewModel
, that will be scoped only inside of fragment lifecycle. So it is important to use in both parts activity context to get the same instance.
Activity part:
TimeTableViewModel viewModel = new ViewModelProvider(this).get(TimeTableViewModel.class);
Fragment part:
TimeTableViewModel viewModel = new ViewModelProvider(getActivity()).get(TimeTableViewModel.class);
Is important that your fragment is located inside the same activity that is using this ViewModel
.
But guys at Google has make it easier for us with some extension methods. But as far as I know, they are working only in Kotlin classes. So if you have Kotlin code, you can declare your ViewModel
simply like this:
private val quizViewModel: TimeTableViewModel by activityViewModels()
For Fragment scoped ViewModel
you need to write something like this:
private val quizViewModel: TimeTableViewModel by viewModels()
But you have to add Kotlin ktx dependency to your project build.gradle
file. For example like this:
implementation 'androidx.fragment:fragment-ktx:1.1.0'
Answered By - BVantur
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.