java - 获取 EditText 输入值并在 TextView 中显示一些计算结果
问题描述
我制作了一个非常基本的加权平均计算器作为 Android 应用程序(在 Java 中),它运行良好。
用户只需在三个s 中输入 3 个值a
, b
,并计算公式:c
EditText
d = 0.25 * a + 0.25 * b + 0.5 * c;
这个数学方程的结果显示在 a 中TextView
,所有这些都MainActivity
在按下按钮时显示。
但是在为更好的 UI 创建了一个新项目(使用 Android Studio 模板 Navigation Drawer Activity)之后,我意识到我的代码无法正常工作。
当我按下按钮时,我如何修改该计算器以在我的片段(名为CalculatorWeightedFragment
)中获取输入以进行计算并在同一片段中的 TextView 中显示结果?
在这一点上,我得到的只是显示一些静态的东西,并且没有分配给按钮的动作。
代码如下:
CalculatorWeightedFragment.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;
}
}
CalculatorWeightedViewModel.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;
}
}
解决方案
基于您的 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(没有LiveData
and ViewModel
)
我创建了一些新的简单片段(例如)
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(使用LiveData
and ViewModel
)
当你使用LiveData
andViewModel
时,你不需要在你的Fragment
. 你可以观察到所有的变化。
您正在创建此片段的活动。要在 Fragment 中拥有 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();
}
}
视图模型
您可以将值 ( a
, b
, c
) 存储为用于不同目的的字段。在这里,我正在重新计算结果,没有任何额外的字段。使其尽可能简单。
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();
}
}
}
它应该像那里一样工作:
推荐阅读
- constraint-programming - Minizinc - 变量值等于 0、0.5 或 1
- reactjs - Ckeditor5 未在 Ant Design 中显示
- python - 如何一次使用 SqlQuery 从数据库中收集所有数据?
- github - 如何更改文件名的大小写
- aws-glue - 处理 Glue 作业时出现 Nullpointer 异常
- sql-server - 如何根据 SQL Server 上的间隔日期和每日成本表计算项目阶段成本
- ios - Firebase/Crashlytics 和 Firebase/Analytics 的 NSUserTrackingUsageDescription 的目的字符串是什么?
- javascript - 如何在 Jquery 选择/选项过滤系统中保留最后的首选项?
- opencv - 如何在 OpenCV 中获得与 ImageMagick 的“convert -fft”完全相同的结果?
- angular - 基于角色的角度路由到子路径