Текстовое представление не обновляется во фрагменте с MVVM MutableLiveData - PullRequest
0 голосов
/ 21 марта 2020

У меня есть 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 Строковые данные для тоста верны.

...