使用ViewModel处理不同片段之间的数据并更新

时间:2018-06-14 10:06:52

标签: android android-fragments viewmodel

我正在尝试实现一个datepicker片段,然后必须将所选日期返回到调用它的片段(父片段)。我已经实现了一个接口,但似乎接口只在活动中调用,而不是在片段中调用(即使我明确地调用它)。我用日志文件检查了这个。

然后我继续使用ViewModel类来保存数据。现在问题是,我能够将数据存储在ViewModel类中,但我不知道在父片段中将ViewModel的函数调用到何处。在OnCreate / OnCreateView上调用它没有帮助,因为片段已经加载。在OnResume / OnAttach上调用它会使用空指针引用崩溃应用程序。

public class ShareData extends ViewModel{

private int year, month, day;

private String date;

public void getDate(int y, int m, int d)
{
    Log.d("Viewmodel is", Integer.toString(year) + " " + Integer.toString(month) + " " + Integer.toString(day));
    year = y;
    month = m;
    day = d;
}

public String setDate()
{

    return (Integer.toString(year) + "-" + Integer.toString(month) + "-" + Integer.toString(day));
}

}

这是DatePicker dialogfragment中的代码:

        public void onDateSet(DatePicker view, int year, int month, int day) {
        viewModel.getDate(year,month+1,day);
        datePicked.onDatePicked(view, year, month+1, day);
        // Do something with the date chosen by the user
    }

这是我的父片段:

   @Override
    public View onCreateView(LayoutInflater inflater, final ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.operations_static_new, container, false);
        name = view.findViewById(R.id.patient_name);
        id = view.findViewById(R.id.patient_id);
        date_textview = view.findViewById(R.id.date_static);

        date_textview.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                confirmDatePicker(); //this opens fragment to choose date
            }
        });
        model = ViewModelProviders.of(getActivity()).get(ShareData.class);
     date_textview.setText(model.setDate());
}

我在哪里调用date_textview.setText以便日期显示在日期选择器的textview上?

1 个答案:

答案 0 :(得分:0)

我在ViewModel中没有看到任何LiveData,它告诉我你没有正确使用它。您应该做的是将ViewModel中的LiveData绑定到要更新的片段。之后,收到观察ViewModel的任何片段的变化通知是微不足道的。

所以从ViewModel开始应该看起来像这样:

// This will now notify the fragment that is observing of any changes made
public class SharedData extends ViewModel {
    private int year, month, day;
    private MutableLiveData<String> date = new MutableLiveData<>();

    // This will notify observing fragments of changes
    public void setDate(int y, int m, int d) {
        year = y; month = m; day = d;
        date.setValue(year + "-" + month + "-" + day);
    }

    // This is a factory method for getting the LiveData the fragment will bind to
    public LiveData<String> getDate() {
        return date;
    }
}

在更新日期更改的片段(父级)内部,您执行类似这样的操作来监视上面示例中的getDate()。在孩子或其他任何事情完成更新后更新发生所需的是:

替换

date_textview.setText(model.setDate());

viewModel.getDate().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String newDate) {
                // Update your view with the new data
                dateTextView.setText(newDate);
            }
        });

设置完成后,您可以从任何地方调用setDate(y,m,d),它将始终更新正在观察它的片段。

https://developer.android.com/topic/libraries/architecture/viewmodelhttps://developer.android.com/topic/libraries/architecture/viewmodel