На основе вашего 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
и 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
и ViewModel
)
Когда вы используете LiveData
и ViewModel
, вам не нужна кнопка на вашем Fragment
. Вы можете наблюдать за всеми изменениями.
Активность, в которой вы создаете этот фрагмент. Чтобы иметь ViewModel во Fragment, вы можете использовать внедрение зависимостей (например, используя библиотеку Dagger) или получить его из ViewModelProviders
(или AndroidViewModelFactory
).
Здесь, чтобы сделать пример максимально простым, я передаю его через конструктор.
Activity
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();
}
}
ViewModel
Вы можете хранить свои значения (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();
}
}
}
Он должен работать так: