首页 > 其他分享 >MainActivity 与 Fragment 之间使用 ViewModel 通信

MainActivity 与 Fragment 之间使用 ViewModel 通信

时间:2022-09-29 00:11:18浏览次数:50  
标签:Fragment ViewModel MainActivity dateValue new TimePickerViewModel public

创建 ViewModel 类

日期选择器的结果保存到 ViewModel,在 MainActivity 中获取 ViewModel 更新之后的值,再把值重新渲染到 UI 上。

public class TimePickerViewModel extends ViewModel {

  private MutableLiveData<String> dateValue;

  public LiveData<String> getDateValue() {
    if (dateValue == null) {
      dateValue = new MutableLiveData<>();
    }
    return dateValue;
  }

  public void setDateValue(String dateValue) {
    this.dateValue.setValue(dateValue);
  }

}

dateValue 需要调用 setValue 函数赋值。getDateValue 函数返回数据之前判断是否已经初始化过值,否则初始化。

创建日期选择器

<TextView
  android:id="@+id/time_picker_text"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_below="@id/title_6"
  android:text="未选择日期"
  android:textColor="@color/black"
  android:textSize="16sp" />

<TextView
  android:id="@+id/time_picker_btn"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_below="@id/title_6"
  android:layout_marginStart="10dp"
  android:layout_toEndOf="@id/time_picker_text"
  android:text="选择日期"
  android:textColor="@color/purple_500"
  android:textSize="16sp" />

初始化 TimePickerFragment 类时,触发 onCreateDialog 函数,把今天的日期的数据获取出来,再实例化 DatePickerDialog:

public class TimePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {

  @NonNull
  @Override
  public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    final Calendar c = Calendar.getInstance();
    int year = c.get(Calendar.YEAR);
    int month = c.get(Calendar.MONTH);
    int day = c.get(Calendar.DAY_OF_MONTH);
    return new DatePickerDialog(getActivity(), this, year, month + 1, day);
  }

  @Override
  public void onDateSet(DatePicker datePicker, int i, int i1, int i2) {
    TimePickerViewModel vm = new ViewModelProvider(requireActivity()).get(TimePickerViewModel.class);
    vm.setDateValue(i + "-" + i1 + "-" + i2);
  }
}

注意 onDateSet 函数,当选择一个日期之后,就会触发该函数。该函数中调用 ViewModelProvider 以修改 TimePickerViewModel 存储的值。ViewModelProvider 需要获取 Activity 的实例,使用 requireActivity() 函数或者 getActivity()。

MainActivity

MainActivity 实现 OnClickListener 接口,这样做的好处就是添加多个事件监听都不需要 new OnClickListener 接口了,直接给 setOnClickListener 函数提供 this 就可以了:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initSpinner();
    findViewById(R.id.time_picker_btn).setOnClickListener(this);
  }

  private void initSpinner() {
    Spinner spinner = findViewById(R.id.spinner);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
      R.array.spinner_values, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);
  }

  @Override
  public void onClick(View view) {
    // 1. 实例化 TimePickerFragment
    TimePickerFragment timePicker = new TimePickerFragment();
    // 2. 显示日期选择器
    timePicker.show(getSupportFragmentManager(), "datePicker");
    // 3. 获取 TextView,待会展示的数据放在这里
    TextView textview = findViewById(R.id.time_picker_text);
    // 4. 观察 ViewModel 数据变化以更新 UI
    TimePickerViewModel timePickerVM = new ViewModelProvider(this).get(TimePickerViewModel.class);
    // 5. 观察数据变化
    timePickerVM.getDateValue().observe(this, e -> {
      textview.setText(timePickerVM.getDateValue().getValue());
    });
  }
}

最主要的就是 onClick 函数里面的代码,点击的适合要先构造一个日期选择器,选中之后,观察 ViewModel 中的数据是否改变,一旦改变就把新的值赋值给 TextView,显示到 UI 上。

标签:Fragment,ViewModel,MainActivity,dateValue,new,TimePickerViewModel,public
From: https://www.cnblogs.com/Enziandom/p/16740052.html

相关文章

  • Fragment的四种跳转方式
    本文主要记录了关于fragment的四种跳转方式:  1、从同一个Activiy的一个Fragment跳转到另外一个Fragment2、从一个Activity的Fragment跳转到另外一个Activity3、从一......
  • 13.Fragment碎片
    1、碎片Fragment是什么?自从谷歌在Android3.0(API11)推出Fragment以后,Fragment就成为了绝大多数APP的必备元素,其重要程度一点也不亚于四大组件。从字面上来看,Fragment的意......
  • WPF DevExpress怎么绑定ViewModel事件
    XAML代码<dxg:GridControl.View><dxg:TableViewx:Name="ProductGridView"ShowGroupPanel="False"AllowColumnFilterin......
  • 27. Fragment + ViewPager
    27.Fragment+ViewPager27.1fragment与viewPager的联合应用ViewPager+Fragment形成翻页效果→减少用户的操作。27.2ViewPager2基本应用新的空白工程布局文......
  • 26. Fragment生命周期
    26.Fragment生命周期26.1Fragment生命周期onAttach()/onDetach():绑定/解绑onCreate()/onDestroy():创建/销毁创建时,解析bundleonCreateView()/onDestroyView():对UI......
  • 24. Fragment的产生、使用方法、静态(动态)添加fragment
    24.Fragment的产生、使用方法、静态(动态)添加fragment24.1Fragment的产生Android3.0之后不同的Fragment运行在同一个Activity之上。24.2什么是Fragment具备生命周......
  • 25. Activity与Fragment通信
    25.Activity与Fragment通信25.1Activity与Fragment通信原生方案:Bundle如何让Activity和BlankFragment1完成通信Activity中://定义一个bundleBundlebundle=newB......
  • ViewPager2+Fragment+TabLayout
    ViewPager22019初Google正式发布了ViewPager2。只要我们已经从Suppor库切换到AndroidX,便可以使用ViewPager2完全取代旧的ViewPager。ViewPager2最显著的特点是基于Recycl......
  • android 动态添加 fragment
    按钮点击触发:publicvoidexecute(Viewview)throwsException{FragmentManagerfm=getFragmentManager();FragmentTransactionft=fm.beginT......
  • Wpf 收到键盘事件时执行 ViewModel 中的命令.
    以 TextBox 中按下 Esc 为例:1<TextBox/>2<TextBox.InputBindings>3<KeyBinding4Key="Escape"5Command="{BindingPa......