android-fragments 获取EditText输入值并在TextView中显示一些计算结果

brjng4g3  于 2022-11-14  发布在  Android
关注(0)|答案(2)|浏览(217)

我做了一个非常基本的加权平均计算器作为Android应用程序(在Java中),它工作得很好。
用户只需在三个EditText中输入3个值abc,然后计算公式:

d = 0.25 * a + 0.25 * b + 0.5 * c;

这个数学方程的结果显示在TextView中,所有这些都在按下一个按钮时显示在MainActivity中。
但在创建了一个新项目以获得更好的UI(使用Android Studio模板Navigation Drawer Activity)后,我意识到我的代码无法正常工作。
我如何修改计算器,以便在我的片段(名为CalculatorWeightedFragment)中获取输入,从而进行计算,并在按下按钮时在同一片段的TextView中显示结果?
在这一点上,我得到的只是一些静态的显示,没有为按钮分配任何操作。
代码如下:

计算器加权片段.java

public class CalculatorWeightedFragment extends Fragment {

    private CalculatorWeightedViewModel calculatorWeightedViewModel;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        calculatorWeightedViewModel =
                ViewModelProviders.of(this).get(calculatorWeightedViewModel.class);
        View root = inflater.inflate(R.layout.fragment_calculator_w, container, false);

        final TextView textView = root.findViewById(R.id.id_result);  // result d stored in id_result

        calculatorWeightedViewModel.takeText().observe(getViewLifecycleOwner(),
                new Observer<String>() {
                    @Override
                    public void onChanged(@Nullable String str) {
                        textView.setText(str);
                    }
                });

        return root;
    }
}

计算器加权视图模型.java

public class CalculatorWeightedViewModel extends ViewModel {

    private MutableLiveData<String> testString;

    public CalculatorWeightedViewModel() {
        testString = new MutableLiveData<>();
        testString.setValue("" + 0.5);
    }

    public LiveData<String> takeText() {
        return testString;
    }
}
kcrjzv8t

kcrjzv8t1#

基于xml布局内容:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/id_a"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/id_b"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/id_c"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/id_buton_rata"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="calculateFunction" />

    <TextView
        android:id="@+id/id_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

示例1(不含LiveDataViewModel

我创建一些新的简单片段(作为示例)

public class CalculatorWeightedFragment extends Fragment {

    private Button button;
    private EditText editTextA;
    private EditText editTextB;
    private EditText editTextC;
    private TextView textViewD;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_calculator_w, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        button = view.findViewById(R.id.id_buton_rata);
        editTextA = view.findViewById(R.id.id_a);
        editTextB = view.findViewById(R.id.id_b);
        editTextC = view.findViewById(R.id.id_c);
        textViewD = view.findViewById(R.id.id_result);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                double result = calculateResult();
                String output = String.format("Result:  %s", result);
                textViewD.setText(output);
            }
        });
    }

    private double calculateResult() {
        try {
            int a = Integer.parseInt(editTextA.getText().toString());
            int b = Integer.parseInt(editTextB.getText().toString());
            int c = Integer.parseInt(editTextC.getText().toString());

            // Result
            return 0.25 * a + 0.25 * b + 0.5 * c;
        } catch (NumberFormatException e) {
            e.printStackTrace();
            return 0;
        }
    }
}

示例2(使用LiveDataViewModel

当你使用LiveDataViewModel时,你不需要在你的Fragment中按按钮。你可以观察到所有的变化。
要在其中创建此片段的Activity。若要在片段中包含ViewModel,可以使用依赖项注入(例如,使用Dagger库)或从ViewModelProviders(或AndroidViewModelFactory)获取它。
在这里,为了使示例尽可能简单,我通过构造函数传递它。

活动

public class MainActivity extends AppCompatActivity {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        CalculatorWeightedViewModel vm = new CalculatorWeightedViewModel();

        CalculatorWeightedFragment fragment = new CalculatorWeightedFragment(vm);

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.add(R.id.frame_layout, fragment);
        transaction.commit();
    }
}

视图模型

你可以将你的值(abc)存储为不同用途的字段。在这里,我重新计算结果的现场,没有任何额外的字段。使它尽可能简单。

package com.example.stack_android;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class CalculatorWeightedViewModel extends ViewModel {

    private MutableLiveData<String> testString = new MutableLiveData<>();

    public LiveData<String> takeText() {
        return testString;
    }

    void updateValues(double a, double b, double c) {
        double result = recalculate(a, b, c);
        String value = "Result: " + result;
        testString.postValue(value);
    }

    void showError() {
        testString.postValue("Wrong Value");
    }

    private double recalculate(double a, double b, double c) {
        return 0.25 * a + 0.25 * b + 0.5 * c;
    }
}

片段:

另外,您可以为每个字段创建单独的侦听器。在这里,我为所有字段使用一个侦听器(名为TextWatcher listener)。

public class CalculatorWeightedFragment extends Fragment {

    private CalculatorWeightedViewModel viewModel;

    private EditText editTextA;
    private EditText editTextB;
    private EditText editTextC;
    private TextView textViewD;

    public CalculatorWeightedFragment(CalculatorWeightedViewModel viewModel) {
        this.viewModel = viewModel;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_calculator_w, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        editTextA = view.findViewById(R.id.id_a);
        editTextB = view.findViewById(R.id.id_b);
        editTextC = view.findViewById(R.id.id_c);
        textViewD = view.findViewById(R.id.id_result);

        TextWatcher listener = new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                textChanged();
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // Not used
            }

            @Override
            public void afterTextChanged(Editable s) {
                // Not used
            }
        };

        editTextA.addTextChangedListener(listener);
        editTextB.addTextChangedListener(listener);
        editTextC.addTextChangedListener(listener);

        viewModel.takeText().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(String newValue) {
                textViewD.setText(newValue);
            }
        });
    }

    private void textChanged() {
        try {
            int a = Integer.parseInt(editTextA.getText().toString());
            int b = Integer.parseInt(editTextB.getText().toString());
            int c = Integer.parseInt(editTextC.getText().toString());

            viewModel.updateValues(a, b, c);
        } catch (NumberFormatException e) {
            viewModel.showError();
            e.printStackTrace();
        }
    }
}

它的工作原理应该是这样的:

a11xaf1n

a11xaf1n2#

你必须在每次编辑中使用textwatcher text

相关问题