Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用ViewModel和update处理不同片段之间的数据_Android_Android Fragments_Viewmodel - Fatal编程技术网

Android 使用ViewModel和update处理不同片段之间的数据

Android 使用ViewModel和update处理不同片段之间的数据,android,android-fragments,viewmodel,Android,Android Fragments,Viewmodel,我试图实现一个datepicker片段,它必须将所选日期返回给调用它的片段(父片段)。我实现了一个接口,但似乎该接口只在活动中被调用,而不是在片段中被调用(即使我显式地调用它)。我用日志文件查过了 然后我继续使用ViewModel类来保存数据。现在的问题是,我能够在ViewModel类中存储数据,但我不知道在父片段中调用ViewModel函数的位置。在OnCreate/OnCreateView上调用它没有帮助,因为片段已经加载。在OnResume/OnAttach上调用它会使具有空指针引用的应用

我试图实现一个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对话框片段中的代码:

        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());
}
这是我的父片段:

   @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上显示日期

我在您的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;
    }
}

viewModel.getDate().observe(这个,新的观察者(){
@凌驾
公共void onChanged(@Nullable String newDate){
//使用新数据更新视图
dateTextView.setText(newDate);
}
});
设置完成后,您可以从任何地方调用setDate(y,m,d),它将始终更新正在观察它的片段


通常在ActivityCreated上实例化ViewModel是个好主意,试试看。是的,我做到了。但是在我已经从dailogfragment中输入日期之后,必须调用textview.setText。现在,我已经通过调用按钮上的.setText来实现了另一个按钮的单击。这是一个糟糕的解决方案,但很好。我不完全理解,您可以将ViewModel声明为
private ViewModel model
,在创建的活动中实例化它,然后在其他地方实例化它。
viewModel.getDate().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String newDate) {
                // Update your view with the new data
                dateTextView.setText(newDate);
            }
        });