У меня есть TextView во фрагменте с MVVM и MutableLiveData, но текст textView не обновляется после setValue для MutableLiveData и устанавливается в обозревателе для textView.
это моя MainActivity java:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportFragmentManager().beginTransaction().replace(R.id.frame_main,new DataFragment()).commit();
//setContentView(R.layout.activity_main);
ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(MainActivity.this,R.layout.activity_main);
ViewModel viewModel = new ViewModel();
activityMainBinding.setViewModel(viewModel);
}
}
это MainActivity XML:
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="viewModel"
type="com.amirhosseinemadi.bmi.viewModel.ViewModel" />
</data>
<LinearLayout 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=".view.MainActivity"
android:orientation="vertical"
android:background="@color/md_grey_200">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="bottom">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:paddingTop="16dp"
android:paddingStart="@dimen/dp16"
android:paddingEnd="@dimen/dp16"
android:gravity="center">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardCornerRadius="@dimen/dp8"
android:backgroundTint="@color/md_white_1000">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/frame_main">
</FrameLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="bottom"
android:paddingStart="@dimen/dp16"
android:paddingEnd="@dimen/dp16"
android:paddingTop="@dimen/dp16"
android:paddingBottom="@dimen/dp8">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="@color/md_light_green_A700"
app:cardCornerRadius="@dimen/dp8">
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintAnimationEnabled="true"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/dp8"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="@dimen/dp48"
android:hint="@string/age"
android:text="@={viewModel.age}"
android:id="@+id/edt_age"
android:inputType="number"
android:backgroundTint="@color/md_white_1000"
android:textColorHint="@color/md_white_1000"
android:drawableStart="@drawable/ic_cake"
android:textColor="@color/md_white_1000"
android:gravity="right">
</androidx.appcompat.widget.AppCompatEditText>
<androidx.appcompat.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="@dimen/dp48"
android:hint="@string/weight"
android:text="@={viewModel.weight}"
android:id="@+id/edt_weight"
android:inputType="number"
android:backgroundTint="@color/md_white_1000"
android:textColorHint="@color/md_white_1000"
android:drawableStart="@drawable/ic_weight"
android:textColor="@color/md_white_1000"
android:gravity="right">
</androidx.appcompat.widget.AppCompatEditText>
<androidx.appcompat.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="@dimen/dp48"
android:id="@+id/edt_height"
android:hint="@string/height"
android:text="@={viewModel.height}"
android:inputType="numberDecimal"
android:backgroundTint="@color/md_white_1000"
android:textColorHint="@color/md_white_1000"
android:drawableStart="@drawable/ic_size"
android:textColor="@color/md_white_1000"
android:gravity="right">
</androidx.appcompat.widget.AppCompatEditText>
</LinearLayout>
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/dp8">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:id="@+id/sexuality">
<androidx.appcompat.widget.AppCompatCheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/woman"
android:layout_marginEnd="@dimen/dp56"
android:id="@+id/check_f"
android:checked="@={viewModel.f}"
android:textColor="@color/md_white_1000"
android:backgroundTint="@color/md_white_1000"
android:buttonTint="@color/md_white_1000">
</androidx.appcompat.widget.AppCompatCheckBox>
<androidx.appcompat.widget.AppCompatCheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/man"
android:id="@+id/check_m"
android:checked="@={viewModel.m}"
android:textColor="@color/md_white_1000"
android:buttonTint="@color/md_white_1000">
</androidx.appcompat.widget.AppCompatCheckBox>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.appcompat.widget.AppCompatButton
android:layout_width="match_parent"
android:layout_height="@dimen/dp48"
android:text="@string/calculate"
android:textSize="@dimen/sp18"
android:id="@+id/btn_calculate"
android:onClick="@{(a)->viewModel.onClick()}"
android:background="@drawable/btn_shape"
android:layout_marginTop="@dimen/dp16"
android:outlineSpotShadowColor="@color/md_white_1000"
android:elevation="0dp">
</androidx.appcompat.widget.AppCompatButton>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</layout>
я устанавливаю значение mutableLiveData в методе Viewmodel onClick
это мой ViewModel:
public class ViewModel extends BaseObservable{
public String weight;
public String height;
public String age;
public Boolean m = false;
public Boolean f = false;
public String min;
public String max;
public String bm = null;
MutableLiveData<Data> mutableLiveData;
public ViewModel() {
mutableLiveData = new MutableLiveData<>();
}
public void onClick()
{
if (!weight.isEmpty()&&!height.isEmpty()&&!age.isEmpty()) {
float w = Integer.parseInt(weight);
float h = Float.parseFloat(height);
float a = Float.parseFloat(age);
BMI bmi = null;
if (w != 0 && h != 0 && a != 0) {
bmi = new BMI();
bmi.setWeight(weight);
bmi.setHeight(height);
bmi.setAge(age);
} else {
Toast.makeText(Application.context, "لطفا اطلاعات را درست وارد کنید", Toast.LENGTH_SHORT).show();
}
if (m == true&&f == true){
Toast.makeText(Application.context, "لطفا یک گزینه را انتخاب کنیذ", Toast.LENGTH_SHORT).show();
}else if (m == false&& f==false)
{
Toast.makeText(Application.context, "لطفا یک گزینه را انتخاب کنیذ", Toast.LENGTH_SHORT).show();
}else
if (m==true || f==true)
{
switch (bmi.getAge())
{
case "18":
if (m==true){
Data data = new Data();
data.setBm(String.valueOf(Application.component.calculator().calculate(bmi)));
data.setMin(String.valueOf(Application.component.calculator().getMin(bmi,0.984f)));
data.setMax(String.valueOf(Application.component.calculator().getMax(bmi,1.024f)));
bm = String.valueOf(Application.component.calculator().calculate(bmi));
mutableLiveData.setValue(data);
}
if (f==true)
{
Data data = new Data();
data.setBm(String.valueOf(Application.component.calculator().calculate(bmi)));
data.setMin(String.valueOf(Application.component.calculator().getMin(bmi,0.947f)));
data.setMax(String.valueOf(Application.component.calculator().getMax(bmi,1.029f)));
mutableLiveData.setValue(data);
}
break;
case "19":
if (m==true){
Data data = new Data();
data.setBm(String.valueOf(Application.component.calculator().calculate(bmi)));
data.setMin(String.valueOf(Application.component.calculator().getMin(bmi,1.011f)));
data.setMax(String.valueOf(Application.component.calculator().getMax(bmi,1.053f)));
mutableLiveData.setValue(data);
}
if (f==true)
{
Data data = new Data();
data.setBm(String.valueOf(Application.component.calculator().calculate(bmi)));
data.setMin(String.valueOf(Application.component.calculator().getMin(bmi,0.963f)));
data.setMax(String.valueOf(Application.component.calculator().getMax(bmi,1.044f)));
mutableLiveData.setValue(data);
}
break;
case "20":
if (m==true){
Data data = new Data();
data.setBm(String.valueOf(Application.component.calculator().calculate(bmi)));
data.setMin(String.valueOf(Application.component.calculator().getMin(bmi,1.033f)));
data.setMax(String.valueOf(Application.component.calculator().getMax(bmi,1.080f)));
mutableLiveData.setValue(data);
}
if (f==true)
{
Data data = new Data();
data.setBm(String.valueOf(Application.component.calculator().calculate(bmi)));
data.setMin(String.valueOf(Application.component.calculator().getMin(bmi,0.963f)));
data.setMax(String.valueOf(Application.component.calculator().getMax(bmi,1.060f)));
mutableLiveData.setValue(data);
}
break;
default:
if (m==true){
Data data = new Data();
data.setBm(String.valueOf(Application.component.calculator().calculate(bmi)));
data.setMin(String.valueOf(Application.component.calculator().getMin(bmi,1f)));
data.setMax(String.valueOf(Application.component.calculator().getMax(bmi,1f)));
mutableLiveData.setValue(data);
}
if (f==true)
{
Data data = new Data();
data.setBm(String.valueOf(Application.component.calculator().calculate(bmi)));
data.setMin(String.valueOf(Application.component.calculator().getMin(bmi,1f)));
data.setMax(String.valueOf(Application.component.calculator().getMax(bmi,1f)));
mutableLiveData.setValue(data);
}
}
}
}else
{
Toast.makeText(Application.context, "لطفا اطلاعات را درست وارد کنید", Toast.LENGTH_SHORT).show();
}
}
public MutableLiveData<Data> getMutableLiveData()
{
return mutableLiveData;
}
}
это мой фрагмент, и я установил текст в mutableLiveData наблюдателя здесь, и текстовое представление не обновляется:
public class DataFragment extends Fragment {
AppCompatTextView bmi ;
ViewModel viewModel;
public DataFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FragmentDataBinding fragmentDataBinding = DataBindingUtil.inflate(inflater,R.layout.fragment_data,container,false);
viewModel = new ViewModel();
fragmentDataBinding.setViewModel(viewModel);
View view = fragmentDataBinding.getRoot();
bmi = fragmentDataBinding.getRoot().findViewById(R.id.txt_bmi);
viewModel.getMutableLiveData().observe(DataFragment.this, new Observer<Data>() {
@Override
public void onChanged(Data data) {
bmi.setText(data.getBm());
}
});
return view;
}
}
это фрагмент xml:
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="viewModel"
type="com.amirhosseinemadi.bmi.viewModel.ViewModel" />
</data>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".view.DataFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dp24">
<com.dinuscxj.progressbar.CircleProgressBar
android:layout_width="@dimen/dp120"
android:layout_height="@dimen/dp120"
app:style="line"
app:progress_text_size="@dimen/sp20"
app:progress_text_color="@color/md_white_1000"
app:progress_background_color="@color/md_green_700"
android:id="@+id/circle_pro"
app:progress_shader="sweep"
app:line_width="@dimen/dp10"
app:progress_start_color="@color/md_green_A700"
app:progress_end_color="@color/md_red_A700"
app:line_count="50">
</com.dinuscxj.progressbar.CircleProgressBar>
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="@color/md_light_green_A700"
android:textSize="30sp"
android:id="@+id/txt_bmi">
</androidx.appcompat.widget.AppCompatTextView>
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/sp18"
android:text=" مناسب"
android:textColor="@color/md_light_green_A700">
</androidx.appcompat.widget.AppCompatTextView>
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/sp18"
android:text=" وضعیت شما :"
android:textColor="@color/md_light_green_A700">
</androidx.appcompat.widget.AppCompatTextView>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/sp18"
android:textColor="@color/md_light_green_A700">
</androidx.appcompat.widget.AppCompatTextView>
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/sp18"
android:text=" تا"
android:textColor="@color/md_light_green_A700">
</androidx.appcompat.widget.AppCompatTextView>
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/sp18"
android:textColor="@color/md_light_green_A700">
</androidx.appcompat.widget.AppCompatTextView>
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/sp18"
android:text="وزن متناسب با قد شما :"
android:textColor="@color/md_light_green_A700">
</androidx.appcompat.widget.AppCompatTextView>
</LinearLayout>
</LinearLayout>
</FrameLayout>
</layout>
после запуска приложения и установки подробности о ActivityMain xml и вызове onClick textView не обновляются, но я, когда делаю тост, bmi Строковые данные для тоста верны.